
В JavaScript массивы можно сортировать с помощью встроенного метода Array.prototype.sort(), который изменяет исходный массив и возвращает его отсортированным. По умолчанию метод сортирует элементы как строки в порядке Unicode, что важно учитывать при работе с числами: [1, 10, 2].sort() вернёт [1, 10, 2], а не [1, 2, 10].
Для корректной сортировки числовых массивов необходимо передавать в sort() функцию сравнения: (a, b) => a — b. Это гарантирует, что элементы будут упорядочены по возрастанию. Для сортировки по убыванию используют (a, b) => b — a. Применение функции сравнения критично при работе с данными, которые не являются строками.
При сортировке сложных объектов, например массивов с объектами вида {name: «Иван», age: 30}, функция сравнения должна учитывать конкретное свойство: (a, b) => a.age — b.age. Такой подход позволяет структурировать данные по числовым и алфавитным признакам без дополнительной трансформации массива.
Помимо встроенного метода, существуют алгоритмы сортировки, которые можно реализовать вручную: быстрая сортировка, сортировка слиянием, пузырьковая сортировка. Быстрая сортировка оптимальна для больших массивов, сортировка слиянием сохраняет стабильность элементов, а пузырьковая сортировка полезна для учебных целей и небольших массивов.
Практическая рекомендация: перед сортировкой массивов с критичными данными создавайте копию с помощью slice(), чтобы избежать изменения исходного массива. Это позволяет контролировать результаты и предотвращает непреднамеренные побочные эффекты при дальнейшей обработке данных.
Как использовать метод sort() для строк и чисел
Метод sort() изменяет исходный массив, упорядочивая его элементы по возрастанию или по указанной функции сравнения.
Сортировка строк

По умолчанию sort() упорядочивает элементы как строки в порядке Unicode:
const fruits = ['банан', 'яблоко', 'апельсин'];
fruits.sort();
console.log(fruits); // ['апельсин', 'банан', 'яблоко']
Для сортировки с учётом регистра и локали используют localeCompare():
const fruits = ['банан', 'Яблоко', 'апельсин'];
fruits.sort((a, b) => a.localeCompare(b, 'ru'));
console.log(fruits); // ['апельсин', 'банан', 'Яблоко']
Сортировка чисел

Без функции сравнения числа сортируются как строки, что даёт некорректный результат:
const numbers = [10, 2, 30, 4];
numbers.sort();
console.log(numbers); // [10, 2, 30, 4] - неверно
Правильная сортировка чисел требует передачи функции сравнения:
numbers.sort((a, b) => a - b); // по возрастанию
console.log(numbers); // [2, 4, 10, 30]
numbers.sort((a, b) => b - a); // по убыванию
console.log(numbers); // [30, 10, 4, 2]
Функция сравнения

Функция принимает два аргумента a и b и должна возвращать:
- отрицательное число, если
aдолжно идти передb; - 0, если порядок не важен;
- положительное число, если
aдолжно идти послеb.
Сортировка сложных массивов
Для массивов объектов используется ключ для сравнения:
const users = [
{name: 'Анна', age: 25},
{name: 'Борис', age: 20},
{name: 'Виктор', age: 30}
];
// По возрасту по возрастанию
users.sort((a, b) => a.age - b.age);
console.log(users);
Метод sort() применим как к строкам, так и к числам, главное правильно определить функцию сравнения для нужного порядка.
Сортировка числового массива с учётом порядка возрастания и убывания

В JavaScript метод sort() используется для сортировки массивов, однако по умолчанию элементы преобразуются в строки, что приводит к некорректной сортировке чисел. Для правильного упорядочивания требуется передать функцию сравнения.
Пример сортировки массива чисел по возрастанию:
const numbers = [12, 5, 20, 8, 3];
numbers.sort((a, b) => a - b);
console.log(numbers); // [3, 5, 8, 12, 20]
Для сортировки по убыванию достаточно изменить порядок вычитания:
numbers.sort((a, b) => b - a);
console.log(numbers); // [20, 12, 8, 5, 3]
Рекомендации при работе с числовыми массивами:
- Всегда используйте функцию сравнения
(a, b) => a - bили(a, b) => b - a, чтобы избежать некорректной сортировки строк. - Если массив содержит отрицательные числа, функция сравнения обеспечивает правильный порядок.
- Для массивов с плавающей точкой
sort()с функцией сравнения корректно упорядочивает значения. - Сортировка выполняется «на месте», поэтому исходный массив изменяется.
Можно использовать slice() для создания копии массива, если нужно сохранить оригинал:
const sortedAsc = numbers.slice().sort((a, b) => a - b);
const sortedDesc = numbers.slice().sort((a, b) => b - a);
При больших массивах сортировка остаётся эффективной, так как sort() использует оптимизированный алгоритм V8, но функция сравнения должна быть простой для минимизации нагрузки.
Сравнительные функции: кастомная сортировка объектов
В JavaScript метод sort() по умолчанию преобразует элементы массива в строки и сравнивает их по Unicode. Для объектов это недостаточно, поэтому используют сравнительные функции. Сравнительная функция принимает два аргумента и возвращает число: отрицательное, если первый элемент должен быть раньше второго; положительное, если позже; ноль, если порядок не изменяется.
Пример сортировки массива объектов по числовому полю age:
const users = [{name: 'Аня', age: 25}, {name: 'Борис', age: 30}, {name: 'Вика', age: 22}];
users.sort((a, b) => a.age - b.age);
Для строковых полей рекомендуется использовать localeCompare для корректной сортировки с учётом языковых особенностей:
users.sort((a, b) => a.name.localeCompare(b.name));
Можно комбинировать несколько критериев. Например, сначала сортировать по возрасту, а при равенстве – по имени:
users.sort((a, b) => a.age - b.age || a.name.localeCompare(b.name));
Для сортировки в обратном порядке достаточно поменять местами аргументы или умножить результат на -1:
users.sort((a, b) => b.age - a.age);
Сравнительные функции позволяют учитывать сложные правила, например, сортировать по длине строки или по кастомным критериям, таким как приоритет статуса или дате. Их использование делает сортировку объектов точной и предсказуемой. При работе с большими массивами стоит помнить, что sort() изменяет исходный массив, поэтому при необходимости создают его копию с помощью slice() перед сортировкой.
Сортировка массивов с датами и временем
Для сортировки массивов с датами и временем в JavaScript стандартный метод sort() требует передачи функции сравнения. Прямое использование array.sort() без неё приведёт к лексикографической сортировке строк, что некорректно для дат.
Если массив содержит объекты Date, функция сравнения должна возвращать разницу в миллисекундах:
dates.sort((a, b) => a - b);
Для массивов строк, представляющих даты, необходимо сначала преобразовать строки в объекты Date:
dates.sort((a, b) => new Date(a) - new Date(b));
Сортировка по времени с точностью до секунд или миллисекунд также возможна через объект Date, используя getTime():
events.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
При работе с различными форматами дат (например, ‘DD.MM.YYYY’ или ‘YYYY/MM/DD’) рекомендуется использовать библиотеку Luxon или date-fns для корректного парсинга перед сортировкой. Пример с date-fns:
import { parseISO } from 'date-fns';
dates.sort((a, b) => parseISO(a) - parseISO(b));
Для сортировки в обратном порядке достаточно изменить местами операнды в функции сравнения:
dates.sort((a, b) => b - a);
Особое внимание стоит уделить временным зонам: сравнивать строки с разными часовыми поясами напрямую нельзя. Преобразуйте все даты к UTC перед сортировкой:
dates.sort((a, b) => new Date(a).getTime() - new Date(b).getTime());
При больших массивах рекомендуется избегать повторного создания объектов Date внутри функции сравнения для повышения производительности. Лучше сначала преобразовать все строки в даты, а затем сортировать массив объектов Date.
Случайная перестановка элементов с shuffle
Для случайной перестановки элементов массива в JavaScript используют алгоритм Фишера–Йетса. Он гарантирует равновероятное распределение элементов и выполняется за O(n).
Пример реализации:
function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
В этом коде цикл идет с конца массива к началу. Переменная j выбирается случайно от 0 до i, после чего элементы array[i] и array[j] меняются местами.
Для массивов с большим количеством элементов избегайте повторного вызова Math.random() внутри вложенных циклов, это замедляет работу и нарушает равномерность распределения.
При необходимости создать новый массив с перемешанными элементами без изменения исходного, используйте slice():
const shuffled = shuffle(originalArray.slice());
Алгоритм корректно работает для массивов любого типа: чисел, строк или объектов. Для объектов важно учитывать, что перемешивается ссылка, а не глубокая копия данных.
Тестирование можно проводить через проверку статистики перестановок: многократный вызов shuffle должен давать приблизительно равное количество появлений каждого элемента в каждой позиции.
Как избежать побочных эффектов при сортировке исходного массива
Метод Array.prototype.sort() изменяет исходный массив. Чтобы сохранить исходные данные, необходимо работать с копией массива. Для числовых массивов это можно сделать с помощью slice() или оператора расширения:
const copy = originalArray.slice();
const copy = [...originalArray];
При сортировке объектов нужно учитывать, что копирование массива создает поверхностную копию. Изменение свойств объектов в копии повлияет на исходный массив. Чтобы полностью изолировать данные, применяется глубокое копирование:
const deepCopy = originalArray.map(item => ({ ...item }));
Для числовых и строковых массивов с нестандартной логикой сортировки рекомендуется передавать функцию сравнения. Это предотвращает непредсказуемый порядок элементов:
copy.sort((a, b) => a - b); для чисел
copy.sort((a, b) => a.localeCompare(b)); для строк
Ниже таблица с конкретными рекомендациями:
| Задача | Решение | Пример кода |
|---|---|---|
| Сохранить исходный массив чисел | Создать поверхностную копию с slice() или [...array] |
const sorted = [...numbers].sort((a,b) => a-b); |
| Сохранить исходный массив объектов | Сделать глубокую копию через map() с деструктуризацией |
const sorted = original.map(obj => ({...obj})).sort((a,b) => a.age-b.age); |
| Сортировка строк с учетом локали | Использовать localeCompare |
const sorted = [...words].sort((a,b) => a.localeCompare(b)); |
| Сортировка чисел без побочных эффектов | Передавать функцию сравнения | const sorted = [...numbers].sort((a,b) => a-b); |
Следуя этим рекомендациям, исходный массив остается неизменным, что предотвращает неожиданные ошибки в дальнейшем коде.
Вопрос-ответ:
Какие методы сортировки массивов есть в JavaScript?
В JavaScript существует встроенный метод sort(), который позволяет сортировать элементы массива. По умолчанию он преобразует элементы в строки и сортирует их по Unicode, поэтому числа могут сортироваться не так, как ожидается. Чтобы правильно сортировать числа, нужно передать в sort() функцию сравнения. Также можно реализовать собственные алгоритмы сортировки, такие как пузырьковая, быстрая или сортировка вставками, если требуется более гибкий контроль над процессом.
Почему при сортировке чисел через arr.sort() результат иногда неверный?
Метод sort() без аргументов сравнивает элементы как строки. Например, числа [10, 2, 5] будут отсортированы как [10, 2, 5], потому что строка «10» идёт перед «2» в порядке Unicode. Чтобы числа сортировались правильно, нужно использовать функцию сравнения: arr.sort((a, b) => a - b). Она возвращает отрицательное значение, если a должно быть перед b, ноль если равны и положительное значение, если a должно идти после b.
Как отсортировать массив объектов по определённому полю?
Для сортировки массива объектов используют функцию сравнения внутри sort(). Например, если есть массив users с полем age, сортировка по возрасту будет выглядеть так: users.sort((a, b) => a.age - b.age). Это упорядочит объекты от наименьшего возраста к наибольшему. Для сортировки по строковому полю можно использовать localeCompare, например: users.sort((a, b) => a.name.localeCompare(b.name)).
Что лучше использовать: встроенный sort() или собственный алгоритм?
В большинстве случаев встроенный sort() достаточно быстрый и удобный для задач на веб-странице. Если нужны специальные условия сортировки или нестандартное поведение, имеет смысл написать собственный алгоритм. Например, если требуется сортировка с учётом стабильности порядка или многокритериальная сортировка, иногда проще реализовать алгоритм самостоятельно. Но для стандартных числовых или строковых массивов встроенный метод обычно эффективен и надёжен.
Можно ли отсортировать массив без изменения исходного?
Да, можно создать копию массива и применить sort() к ней, чтобы оригинальный массив остался без изменений. Например: const sortedArr = [...arr].sort((a, b) => a - b). Здесь оператор ... создаёт поверхностную копию массива, после чего сортировка затрагивает только копию. Это полезно, когда нужно сохранить исходные данные или работать с несколькими вариантами отсортированного массива одновременно.
