Как отсортировать числовой массив?
Как отсортировать массив объектов по нескольким полям?
Функция sort
по умолчанию приводит элементы массива к строкам, а затем сортирует.
[1,-8,90,32,0,0,5,92,900].sort()
// [-8, 0, 0, 1, 32, 5, 90, 900, 92]
Если массив состоит из чисел, то такое поведение является нежелательным.
Использование компаратораФункция sort
может принимать аргумент - компаратор.
Компаратор - это функция, которая принимает 2 аргумента и возвращает отрицательное число, если первый меньше, положительное, если второй меньше и 0, если они равны.
Для чисел достаточно распространено использование вычитания в качестве компаратора:
[1,-8,90,32,0,0,5,92,900].sort(function(a, b) {
return a-b;
})
// [-8, 0, 0, 1, 5, 32, 90, 92, 900]
Вообще, следует с осторожностью относиться к этой конструкции из-за возможного переполнения, но в большинстве случаев она работает.
Компаратор на основе сравненияМожно вспомнить, что во многих языках true приводится к 1, а false - к 0.
Воспользуемся этой возможностью. Только одно из условий a<b
и b<a
истинно, поэтому разность (b<a) - (a<b)
замечательно подходит на роль компаратора:
[1,-8,90,32,0,0,5,92,900].sort(function(a, b) {
return (b<a) - (a<b);
})
// [-8, 0, 0, 1, 5, 32, 90, 92, 900]
Какие тут плюсы? Помимо невозможности переполнения, такое сравнение можно использовать не только с числами. Например, строки вычитать мы не можем, а сравнивать можем.
Для сортировки по убыванию надо просто поменять сравнения местами:
[1,-8,90,32,0,0,5,92,900].sort(function(a, b) {
return (a<b) - (b<a);
})
// [900, 92, 90, 32, 5, 1, 0, 0, -8]
Сортировка по нескольким полям
При сравнении по нескольким полям требуется, чтобы следующее поле сравнивалось только когда предыдущие равны. Это значит, что часть компаратора, выполняющая сравнение тех полей при вычислении даёт 0.
Таким образом, для объединения сравнений полей замечательно подходит оператор ||
, возвращающий первое истинное (в нашем случае ненулевое) значение, либо самое последнее (в нашем случае 0), если все ложны. Таким способом можно объединить любое количество полей.
Отсортируем массив по имени и id:
[{name:"John", id:7}, {name:"John",id:4}, {name:"Adam",id:3}, {name:"Adam",id:30}, {name:"Rose",id:1}].sort(function(a, b) {
return (b.name<a.name) - (a.name<b.name) || (b.id<a.id) - (a.id<b.id);
})
// [{"name":"Adam","id":3},{"name":"Adam","id":30},{"name":"John","id":4},{"name":"John","id":7},{"name":"Rose","id":1}]
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Подскажите, пожалуйста, почему в переменную thischaracter2[i] записывается только один объект?
Всем приветПрочитал про такое api, как Intersection Observer, но использовать это, почему-то не состояние
функция parseInt превращает из 16 системы счисления в 10 систему счисления, а можно наоборот ? Или нужно использовать toString ?