Как делать сортировку в JavaScript при помощи sort() | by Stas Bagretsov

🥳 Подписывайтесь на мой Twitter! ↪️ @stassonmars — теперь там ещё больше из мира фронтенда, да и вообще поговорим. 🪀Подписывайтесь, скоро будет много нового и ещё больше интересного ✨

В этой статье вы узнаете как делать сортировку в JavaScript при помощи метода sort(), не только обычную, как предполагает этот метод, а с задаваемыми параметрами и в самом конце вы узнаете как сортировать объекты, вложенные в массив по различным критериям.

Переводы статей:

Sorting a JavaScript array using array.sort() и Sorting an array of objects

Сортировка массивов в JavaScript делается через метод array.sort(), этот метод возможно также недооценен, как и неверно многими понимаем. Во время вызова sort(), сам по себе он сортирует массив в алфавитном порядке, но не всё так просто, если попытаться зайти дальше. Давайте более детально посмотрим на работу этого метода.

Сортировка массива в алфавитном порядке

Выполнить такую сортировку довольно просто. Просто вызовите array.sort() без любых параметров:

//Алфавитная сортировка в возрастающем порядке:var myarray=["Bob", "Bully", "Amy"]myarray.sort() // Массив становится ["Amy", "Bob", "Bully"]

Обратите внимание на возрастающий порядок. Чтобы сделать его убывающим, то самым простым способом тут будет применение другого метода для массивов в комбинации с sort() — это reverse().

//Алфавитная сортировка в убывающем порядке:var myarray=["Bob", "Bully", "Amy"]myarray.sort()myarray.reverse() //Массив становится ["Bully", "Bob", "Amy"]

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

var myarray=[7, 40, 300]myarray.sort() //Теперь он становится таким [300,40,7]

Хотя 7 в численном порядке меньше, чем 40 или 300, в лексикографическом порядке, семёрка больше, таким образом она оказывается в правее всех в отсортированном массиве. Всегда имейте в виду, что по-дефолту array.sort() сортирует элементы в лексикографическом порядке.

Итак, мы узнали то, что нужно знать для простого использования этого метода. Но существует куда больше, связанного с ним, чем может показаться с первого взгляда. Array.sort() допускает дополнительные параметры в виде функций, которые очень сильно могут помочь в сортировке массива, основываясь на любом заданном критерии, таком как сортировке массива в числовом порядке или перемешанная сортировка.

Передаём функцию в array.sort()

Как говорилось выше, array.sort() допускает дополнительные параметры в виде функций (давайте назовем её sortfunction). Формат такой функции будет выглядеть таким образом:

function sortfunction(a, b){
//Тут можно сказать, что сравнивается a и b, и возвращается -1, 0 или 1.
}
array.sort(sortfunction)

Когда такая функция передаётся в array.sort(), элементы массива сортируются, основываясь на взаимосвязи между каждой парой элементов a и b и значением, отдаваемым функцией. Есть три возможных числа, которые отдадутся функцией:<0 (меньше нуля), 0, >0 (больше нуля).

В первом случае, когда меньше нуля, a отсортируется с индексом меньшими, чем b.

При нуле: a и b будут рассматриваться как равные и сортировка производиться не будет.

Больше нуля: Сортировка b будет меньшего индекса, чем a.

То есть, для того, чтобы сортировка прошла по числам и в возрастающем порядке, функция-параметр должна быть такой:

function sortfunction(a, b){
return (a — b)
}

Дальше больше.

Чтобы отсортировать массив в числовом порядке, просто передайте sortfunction к array.sort(), а затем возвратите разницу между a и b, оба параметра автоматически отправятся в функцию:

var myarray=[25, 8, 7, 41]
myarray.sort(function(a,b){
return a — b
}) //Массив будет [7, 8, 25, 41]

Это работает так, как и должно работать, так как всякий раз когда a меньше, чем b, возвращается негативное значение, что ведет к тому, что меньший элемент всегда будет выставляться левее большего, а другими словами, порядок будет выстроен по возрастанию. Обратите внимание на то, что мы определили нашу функцию сортировки прямо внутри sort(), как анонимную, вместо того, чтобы создавать отдельную функцию и передавать ещё в sort() — оба варианта выдадут одинаковый результат.

Сортировка массива в числовом порядке, но по убывающей, отличается не многим и всего лишь требует реверса двух операндов a и b:

var myarray=[25, 8, 7, 41]
myarray.sort(function(a,b){
return b — a
}) //Массив становится [41, 25, 8, 7]

Делаем случайный порядок у массива

Чтобы перетасовать элементы в массиве нам нужно, чтобы sortfunction возвращал <0, 0 или >0 рандомно, независимо от того, что выдаст a и b. Вот небольшой трюк с этим делом:

//Рандомный порядок в массиве:var myarray=[25, 8, "George", "John"]
myarray.sort(function(){
return 0.5 — Math.random()
}) //Теперь элементы перемешаны

В общем, смело пробуйте в этом редакторе.

Как вы видите у array.sort() есть тайные стороны. На самом деле, вы даже можете сортировать массивы, которые содержат не только примитивы, а объекты со свойствами. Давайте рассмотрим этот вариант:

Сейчас мы пойдем дальше и предположим, что ваш массив содержит не только простые численные или строковые значения, а вместо них объекты со свойствами:

var employees=[]employees[0]={name: "George", age: 32, retiredate: "March 12, 2014"}employees[1]={name: "Edward", age: 17, retiredate: "June 2, 2023"}employees[2]={name: "Christine", age: 58, retiredate: "December 20, 2036"}employees[3]={name: "Sarah", age: 62, retiredate: "April 30, 2020"}

Массив employees — это массив, состоящий из объектов со свойствами разного типа, от строк, чисел до дат (в данном случае строка с датой). Метод sort() можно использовать для сортировки массива, основываясь на значениях одного из свойств, например сортировке по имени, возрасту и в нашем случае, даже дате выхода на пенсию. В общем, тут идея довольно простая, вам нужно изменить функцию сравнения таким образом, что она сравнивала требуемые значения свойств. Давайте посмотрим как это работает.

Сортировка по возрасту

Итак, давайте начнем сортировать наш массив employees по возрасту сотрудников в возрастающем порядке. Вот функция сравнения, которая это сделает:

employees.sort(function(a, b){  return a.age-b.age})

С методом сортировки, указанным выше, наш массив теперь сортируется по свойству age (т.е. возраст). И таким образом, теперь у нас employee[0] это Edward, а employee[1] это George. Этот процесс очень похож на сортировку массива с числовыми значениями по возрастающей, но тут вместо вычета простого b из a, нам надо вычесть b.age из a.age, или иными словами свойство элемента, который мы хотим отсортировать.

Сортировка по имени

В наши дни сортировка по возрасту сотрудника может выглядеть довольно бесчувственной и некорректной, так что давайте отсортируем по именам сотрудников в возрастающем порядке. Вспомните, что по-дефолту, сортировка массива, который содержит примитивы, такие как строки, происходит в алфавитном порядке. Что говорит о том, что вам просто надо вызвать sort() метод, без любой функции сравнения, в общем просто myarray.sort(). Это не работает, так как данные по которым мы хотим отсортировать не являются массивом. Так что же делать? Фокус тут в том, чтобы вручную написать функцию сравнения, которая отсортирует массив по-алфавиту, что в свою очередь даст нам указать где находятся данные строк. Давайте посмотрим:

employees.sort(function(a, b){var nameA=a.name.toLowerCase(), nameB=b.name.toLowerCase()if (nameA < nameB) //сортируем строки по возрастанию  return -1if (nameA > nameB)  return 1return 0 // Никакой сортировки})

Это отсортирует массив employees по именам в возрастающем порядке, так что теперь employee[0] это Christine, employee[1] это Edward и так далее. Тут мы сравниваем две строки a.name с b.name и возвращаем -1, 1 или 0, в соответствии с сортировкой, точно определенной формулой, которую использует сам sort(), без передачи какой-либо другой функции. Как вы уже наверное выяснили, в JavaScript вы можете без сомнений сравнивать две строки.

Сортировка по дате

И наконец, предположим, что вам нужно отсортировать сотрудников по их дате выхода на пенсию. Эта информация хранится в свойстве retiredate и чтобы сделать всё интереснее, это будет не объект с датой, а просто строка. Что нам нужно сделать первым делом, так это создать валидный объект даты из строки даты выхода на пенсию, хоть впоследствии процесс и будет таким же, как и сортировка по числам:

employees.sort(function(a, b){var dateA=new Date(a.retiredate), dateB=new Date(b.retiredate)return dateA-dateB //сортировка по возрастающей дате})

Это отсортирует массив таким образом, что работник, выходящий на пенсию раньше всех, появится первым. employees[0] теперь будет Sarah. Это сработает, потому что JavaScript даст вам сравнить и/или сделать арифметические вычисления на объекте даты, который в первую очередь автоматически сконвертируется в числовой вид.

массив сортировки — npm

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

 const sortArray = требуется ('массив сортировки') 

Краткий обзор

Несколько тривиальных примеров для демонстрации типичного использования.

Сортировка массива примитивов

По возрастанию

Сортировка массива строк по возрастанию (по умолчанию).

 > const partsOfTheDay = ['сумерки', 'день', 'утро', 'вечер']
> sortArray (части дня)
['день', 'вечер', 'утро', 'сумерки'] 
По убыванию

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

 > sortArray (partsOfTheDay, { порядок: 'описание' })
[ 'сумерки', 'утро', 'вечер', 'день'] 
Пользовательский порядок сортировки

Значением по умолчанию для options. order

является 'asc' . Вы также можете указать 'desc' или имя свойства из объекта customOrders . Например, отсортируйте части дня по порядку их появления.

 > sortArray(partsOfTheDay, {
  порядок: «время»,
  заказные заказы: {
    время: ['утро', 'день', 'вечер', 'сумерки']
  }
})
['утро', 'день', 'вечер', 'сумерки'] 

Сортировка массива объектов

Сортировка по свойству объекта

Передайте одно или несколько имен свойств в options.by , чтобы отсортировать массив объектов по этим свойствам.

 > постоянные репозитории = [
  { name: '75lb/sort-array', openIssues: 0, closeIssues: 4},
  { имя: 'lwsjs/локальный веб-сервер', openIssues: 4, CloseIssues: 80},
  {имя: 'jsdoc2md/jsdoc-api', openIssues: 3, CloseIssues: 47}
]
>
sortArray(репозитории, { автор: 'openIssues', порядок: 'убыль' }) [ { имя: 'lwsjs/локальный веб-сервер', openIssues: 4, CloseIssues: 80}, {имя: 'jsdoc2md/jsdoc-api', openIssues: 3, CloseIssues: 47}, { name: '75lb/sort-array', openIssues: 0, ClosedIssues: 4} ]
Сортировать по вычисляемому полю

Сортировать по вычисляемому полю, т. е. по вычисляемому значению, которого нет во входном наборе данных. Определите вычисляемые поля в объекте options.computed , где каждое значение является функцией, которая принимает элемент массива в качестве входных данных и возвращает примитивное значение для сортировки. В этом примере мы сортируем по

всего (имя вычисляемого поля указано в options.computed ).

 > постоянные репозитории = [
  { name: '75lb/sort-array', openIssues: 0, closeIssues: 4},
  { имя: 'lwsjs/локальный веб-сервер', openIssues: 4, CloseIssues: 80},
  {имя: 'jsdoc2md/jsdoc-api', openIssues: 3, CloseIssues: 47}
]
> sortArray(репозитории, {
  по: «всего»,
  порядок: 'убыль',
  вычислено: {
    итого: репозиторий => репозиторий.openIssues + репозиторий.closedIssues
  }
})
[
  { имя: 'lwsjs/локальный веб-сервер', openIssues: 4, CloseIssues: 80},
  {имя: 'jsdoc2md/jsdoc-api', openIssues: 3, CloseIssues: 47},
  { name: '75lb/sort-array', openIssues: 0, ClosedIssues: 4}
] 
Сортировка по глубинным значениям объекта

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

 > постоянные данные = [
  {внутренний: {число: 2}},
  {внутренний: {число: 3}},
  { внутренний: { число: 1 } }
]
> sortArray(данные, {
  по: 'номеру',
  вычислено: {
    номер: строка => строка.внутренний.номер
  }
})
[
  {внутренний: {число: 1}},
  {внутренний: {число: 2}},
  { внутренний: { число: 3 } }
] 
Сортировка по нескольким полям

Сортировка по нескольким столбцам с использованием нескольких пользовательских порядков.

 > постоянные атрибуты = [
  { навык: «точность», уверенность: «средний»},
  { навык: «сила», уверенность: «высокий»},
  { навык: 'скорость', уверенность: 'низкая'},
  { навык: 'сила', уверенность: 'низкий'},
  { навык: 'скорость', уверенность: 'высокая'},
  { навык: «точность», уверенность: «низкая»},
  { навык: «скорость», уверенность: «средний»},
  { навык: «точность», уверенность: «высокая»},
  { навык: "сила", уверенность: "средний"}
]
> sortArray(атрибуты, {
  по: ['навык', 'уверенность'],
  порядок: ['навык', 'уверенность'],
  заказные заказы: {
    умение: ['точность', 'скорость', 'сила'],
    уверенность: ['низкий', 'средний', 'высокий'],
  }
})
[
  { навык: «точность», уверенность: «низкая»},
  { навык: «точность», уверенность: «средний»},
  { навык: «точность», уверенность: «высокая»},
  { навык: 'скорость', уверенность: 'низкая'},
  { навык: «скорость», уверенность: «средний»},
  { навык: 'скорость', уверенность: 'высокая'},
  { навык: 'сила', уверенность: 'низкий'},
  { навык: «сила», уверенность: «средний»},
  { навык: «сила», уверенность: «высокий» }
] 

Пожалуйста, посетите вики sort-array для получения дополнительных примеров.

Справочник API

sort-array

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

Пример

 const sortArray = require('sort-array') 
sortArray(array, [options]) ⇒
Массив

Тип : Экспортированная функция
Возвращает : Массив — Возвращает переданный массив.

Параметр Тип Описание
массив Массив Входной массив для сортировки. Разбирается на месте.
[опции] объект Параметры сортировки.
[options.by] Массив.<строка> Одно или несколько имен свойств или вычисляемых полей для сортировки. Указание имен свойств имеет смысл только при сортировке массива объектов.
[опции.заказ] Массив.<строка> Один или несколько порядков сортировки. Укажите 'asc' , 'desc' или имя свойства из объекта options.customOrders
.
[options.customOrders] объект Объект словаря, содержащий один или несколько пользовательских заказов. Каждое значение пользовательского порядка должно быть массивом, определяющим порядок, в котором должны быть отсортированы ожидаемые значения.
[параметры.вычислено] объект Объект словаря, содержащий одну или несколько функций вычисляемого поля. Функция будет вызываться один раз для каждого элемента массива. Каждый вызов будет получать элемент массива в качестве входных данных и должен возвращать примитивное значение, по которому можно отсортировать массив.
[options.nullRank] номер Настраивает, будут ли пустых значений сортироваться до или после определенных значений. Установите на -1 для до, 1 для после. По умолчанию 1 .
[options.undefinedRank] номер Настраивает, будут ли неопределенные значения сортироваться до или после определенных значений. Установите -1 для до, 1 для после. По умолчанию
1
.

Загружать куда угодно

Эта библиотека совместима с Node.js, Интернетом и любым типом загрузчика модулей. Его можно загрузить где угодно, нативно без транспиляции.

Node.js:

 const sortArray = require('sort-array') 

В Node.js с включенной поддержкой модуля ECMAScript:

 import sortArray from sort-array 

В современном браузере Модуль ECMAScript:

 импортировать sortArray из '. /node_modules/sort-array/dist/index.mjs' 

Старый браузер (добавляет window.sortArray ):

 

© 2015-22 Ллойд Брукс <[email protected]>.

Изоморфный набор тестов с помощью тестового и веб-исполнителя. Документировано jsdoc-to-markdown.

Сортировка массива объектов по двум свойствам в JavaScript | Matt Croak Код

Недавно я работал над способом сортировки массива объектов в алфавитном порядке на основе двух столбцов. Это означает, что должны поддерживаться оба уровня алфавитной сортировки. См. пример ниже.

 var fruit = [ 
{colA: 'яблоко', colB: 'красное вкусное'},
{colA: «груша», colB: «красный анжуйский»},
{colA: «апельсин», colB: «пупок»},
{colA: «апельсин», colB: «кровь»},
{colA: «кровь» 'груша', colB: 'зеленый анжу'},
{colA: 'яблоко', colB: 'бабушка кузнец'},
{colA: 'апельсин', colB: 'клементин'}
]

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

 [ 
{colA: "яблоко", colB: "бабушка Смит"},
{colA: "яблоко", colB: "красное вкусное"},
{colA: "апельсин", colB: "кровь"},
{colA: "апельсин", colB: "клементин"},
{colA: "апельсин", colB: "пупок"},
{colA: "груша", colB: "зеленый анжу"},
{colA: "груша", colB: "красный анжу"}
]

Теперь вы можете сначала просто отсортировать фруктов по colA . Затем, когда у вас есть новый отсортированный массив, выполните вторую сортировку на основе colB . Давайте посмотрим, что произойдет, если мы это сделаем.

 console.log(fruits.sort((a, b)=> a.colA < b.colA ? -1 : 1).sort((a, b)=> a.colB < b.colB ? -1 : 1))> [{colA: "апельсин", colB: "кровь"}, 
{colA: "апельсин", colB: "клементин"},
{colA: "яблоко", colB: "бабушка Смит"},
{colA: "груша", colB: "зеленый анжу"},
{colA ": "апельсин", colB: "пупок"},
{colA: "груша", colB: "красный анжу"},
{colA: "яблоко", colB: "красный восхитительный"}]

Получить все моего последнего контента, создав учетную запись в партнерской программе Medium и подписавшись на мою электронную почту. 🙂

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

Так как же нам отсортировать по colA , а затем по colB , не нарушая исходный порядок сортировки?

Хитрость в том, что мы не хотим пересортировать отсортированный список. Это игнорирует исходный порядок сортировки. Внедряя новую функцию сортировки, вы устанавливаете совершенно другой порядок сортировки, а не сортировку в тандеме с существующим. Итак, что нам нужно сделать, это иметь одну функцию сортировки , которая учитывает оба ограничения . Вот как мы можем это сделать.

Сначала проверьте первое ( a.colA < b.colA ) ограничение сортировки. Нам нужно проверить, действительно ли эти два свойства различны. Если они разные, то выполните сортировку. Если это не так, мы не можем отсортировать их на основе первого ограничения.

Это , когда мы будем использовать нашу вторую точку сравнения ( a.colB < b.colB ). Таким образом, мы сравниваем элементы массива с одинаковыми colA (то есть уже в правильном порядке), а затем выполнить вторую сортировку в текущем порядке. См. код ниже.

 console.log(fruits.sort((a, b)=> { 
if (a.colA === b.colA){
return a.colB < b.colB ? -1 : 1
} else {
return a.colA < b.colA ?-1 : 1
}
}))> [{colA: "яблоко", colB: "бабушка кузнец"},
{colA: "яблоко", colB: "красное вкусное "},
{colA: "апельсин", colB: "кровь"},
{colA: "апельсин", colB: "клементин"},
{colA: "апельсин", colB: "пупок"},
{colA: "груша", colB: "зеленый анжу"},
{colA: "груша", colB: "красный анжу"}]

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