Сортировка массивов чисел в JavaScript с помощью метода sort

Метод массивов sort позволяет сортировать элементы массива и управлять выполнением сортировки. Цель этой статьи – объяснить, как работает метод sort при сортировке массива чисел.

Примечание: Сортировать массив чисел в порядке возрастания можно с помощью:

myArray.sort((a, b) => a - b);

Массивы в JavaScript – это структуры данных, состоящие из набора элементов. Поскольку Javascript не является типизированным языком, массивы Javascript могут содержать элементы разных типов — строки, числа, неопределенные данные и т.д. Однако чаще всего рекомендуется, чтобы все элементы в массиве были одного типа.

Сортировка – одна из многих операций, которые можно выполнять с массивами. Путем сортировки можно, к примеру, быстро определить лучших учеников на основании оценок или вычислить, сколько данных вы потребляли в последнее время.

Предположим, у нас есть гнездо, в котором хранится определенное количество яиц. В приведенных ниже примерах мы отсортируем их по возрастанию и убыванию.

Заполнение массива

Давайте объявим и инициализируем вложенный массив и предварительно заполним его нулевыми значениями (это временно):

let eggsInNest = new Array(10).fill(null);

Мы используем метод fill, доступный в методе конструкторе Array. Затем давайте добавим в массив 10 элементов со случайными значениями от 1 до 200:

eggsInNest = eggsInNest.map(() => (Math.floor(Math.random() * 200) + 1));

Сортировка в порядке возрастания

Затем мы можем выполнить сортировку, просто вызвав в массиве метод sort  без аргументов:

eggsInNest.sort();
// e.g.: [109, 136, 156, 188, 19, 190, 2, 34, 55, 90]

Как видите, возникла небольшая проблема, и сортировка прошла не совсем так, как вы могли ожидать. Дело в том, что по умолчанию метод sort():

  1. сортирует массив в порядке возрастания,
  2. а элементы привязывает к строкам.

Для этого метод sort вызывает метод String() для каждого элемента массива, а затем сравнивает эквивалентные строки, чтобы определить правильный порядок.

То есть по факту элементы сравниваются как строки и сортируются так, как если бы они были строками символов, а не числами. Получается, в большинстве случаев использовать метод sort без метода обратного вызова не имеет смысла, потому что сортировка выполняется не так, как мы того ожидаем. Поэтому нам нужно явно указать, как это сделать – с помощью функции обратного вызова.

Функция обратного вызова (технически это функция сравнения) принимает два аргумента (по соглашению называемые a и b) и должна возвращать 1, если первый аргумент должен предшествовать второму; -1, если второй аргумент должен предшествовать первому; и 0, если они одинаковы. Звучит запутанно.

Давайте создадим функцию сравнения sortEggsInNest:

function sortEggsInNest(a, b) {
if (a > b) {
return 1;
} else if (b > a) {
return -1;
} else {
return 0;
}
}

Если вы хотите пойти дальше, вы можете сократить функцию сравнения sortEggsInNest с помощью тернарного оператора:

function sortEggsInNest(a, b) {
return a > b ? 1 : b > a ? -1 : 0;
}

Затем мы можем снова вызвать метод sort, но на этот раз передать ему функцию сравнения sortEggsInNest:

eggsInNest.sort(sortEggsInNest);

Теперь массив будет отсортирован правильно – в порядке возрастания.

Сортировка в порядке убывания

А что делать, если нужно отсортировать числа в массиве по убыванию? Просто замените return 1 в функции сравнения на return -1, вот так:

function sortEggsInNest(a, b) {
if (a > b) {
return -1;;
} else if (b > a) {
return 1;;
} else {
return 0;
}
}

А вот краткая версия с использованием тернарных операторов:

function sortEggsInNest(a, b) {
return a > b ? -1 : b > a ? 1 : 0;
}

Краткие функции сравнения

Есть еще более короткий способ написать функцию сравнения. Вот он:

eggsInNest.sort((a, b) => a - b);

Это нормальный синтаксис, потому что функция сравнения возвращает только 1, -1 или 0. Вычитание двух промежуточных значений дает именно это. Однако имейте в виду – этот вариант зписи можно использовать только с числовыми типами или объектами, метод valueOf() которых возвращает числовые значения (например, объект Date).

Заключение

sort — один из многих методов-модификаторов массивов (к ним также относятся shift, splice, reverse и т.п.).

Читайте также: Методы массивов в JavaScript: модификаторы

Tags:

Добавить комментарий