JS метод Array.sort()
Опис
Метод sort()
сортує елементи масиву на місці і повертає посилання на той же масив, але вже відсортований. За замовчуванням порядок сортування є зростаючим, він базується на перетворенні елементів у рядки, а потім порівнянні їх послідовностей значень кодових одиниць UTF-16.
У випадку, коли функція compareFn
не задана, всі невизначені елементи масиву сортуються шляхом перетворення їх у рядки та порівняння рядків у порядку кодових одиниць UTF-16. Наприклад, "banana" передує "cherry". При числовому сортуванні 9 передує 80, але через перетворення чисел у рядки, "80" вище "9" у порядку Unicode. Усі невизначені елементи сортуються в кінець масиву.
Метод sort()
зберігає порожні слоти. Якщо вихідний масив має розріджену структуру, порожні слоти переміщуються в кінець масиву та завжди йдуть після всіх невизначених елементів.
У випадку, коли надана функція compareFn
, всі невизначені елементи масиву переміщаються в кінець масиву без виклику compareFn
. Усі визначені елементи масиву сортуються відповідно до значення, яке повертає функція порівняння compareFn
.
Отже, функція порівняння має таку форму:
function compareFn(a, b) {
if (a менше b за якимось критерієм упорядкування) {
return -1;
}
if (a більше b за критерієм упорядкування) {
return 1;
}
// a має бути рівним b
return 0;
}
Вимоги до порівняльника (compareFn
) мають такі властивості, щоб гарантувати правильну поведінку сортування:
- Чистота (Pure): Порівняльник не вносить змін до об'єктів, які підлягають порівнянню, і не впливає на зовнішній стан. Це критично, оскільки невідомо, коли саме буде виконано порівняння. Отже, жоден окремий виклик не має створювати видимих змін в зовнішньому середовищі.
- Стабільність (Stable): Результат роботи порівняльника для однакових вхідних даних завжди має бути однаковим.
- Рефлексивність (Reflexive):
compareFn(a, a) === 0
. - Антисиметричність (Anti-symmetric): Як
compareFn(a, b)
, так іcompareFn(b, a)
або обидва дорівнюють 0, або мають протилежні значення. - Транзитивність (Transitive): Якщо
compareFn(a, b)
іcompareFn(b, c)
мають однаковий знак (або нульове значення), тоcompareFn(a, c)
також має цей знак.
Ефективний порівняльник може повертати лише одне з трьох значень: 1
, 0
або -1
. Якщо він завжди повертає 0
, це означає, що порядок масиву не зміниться, але порівняльник вважається надійним.
Для порівняння чисел замість рядків можна просто відняти b
від a
. Ось функція, що сортує масив у порядку зростання (за умови, що він не містить значень Infinity
та NaN
):
function compareNumbers(a, b) {
return a - b;
}
Метод sort()
є універсальним. Він очікує, що значення this
матиме властивість length
та властивості з цілими числовими ключами. Хоча рядки також мають подібну структуру масиву, цей метод не підходить для їх застосування, оскільки рядки є незмінними.
Порада: | Ви можете передати функцію порівняння у метод
|
Порада: | Метод |
Порада: | Якщо ви хочете, щоб
|
Порада: | Щоб відсортувати елементи в масиві без змінення оригінального масиву, використовуйте |
Синтаксис
sort()
sort(compareFn)
Параметри
compareFn
Функція, яка визначає порядок сортування. Значення, що повертається, повинно бути числом, знак якого вказує на відносний порядок двох елементів: від'ємне, якщо
a
меншеb
, додатнє, якщоa
більшеb
, і нуль, якщо вони рівні.NaN
розглядається як0
.Функція
compareFn
викликається з наступними аргументами:a
: Перший елемент для порівняння. Ніколи не будеundefined
.b
: Другий елемент для порівняння. Ніколи не будеundefined
.
Якщо пропущено, елементи масиву перетворюються на рядки, а потім сортуються відповідно до значення Unicode кожного символу.
Return
reference
Посилання на вихідний масив, який був відсортований. Зверніть увагу, що масив сортується на місці, без створення копії.
Переглядачі
Переглядач | |||||
---|---|---|---|---|---|
1 |
1 |
1 |
4 |
12 |
Переглядач | ||||
---|---|---|---|---|
4.4 |
18 |
4 |
1 |
Переглядач | ||
---|---|---|
0.10.0 |
1.0 |
Приклади
Цей приклад демонструє, як метод sort()
сортує елементи масиву як рядки, що може привести до неочікуваних результатів при сортуванні чисел. Додатково демонструється робота з функцією порівняння для правильного сортування чисел.
Створення, відображення та сортування масиву.
const stringArray = ["Синій", "Горбатий", "Білуха"];
const numberArray = [40, 1, 5, 200];
const numericStringArray = ["80", "9", "700"];
const mixedNumericArray = ["80", "9", "700", 40, 1, 5, 200];
function compareNumbers(a, b) {
return a - b;
}
stringArray.join(); // 'Синій,Горбатий,Білуха'
stringArray.sort(); // ['Білуха', 'Синій', 'Горбатий']
numberArray.join(); // '40,1,5,200'
numberArray.sort(); // [1, 200, 40, 5]
numberArray.sort(compareNumbers); // [1, 5, 40, 200]
numericStringArray.join(); // '80,9,700'
numericStringArray.sort(); // ['700', '80', '9']
numericStringArray.sort(compareNumbers); // ['9', '80', '700']
mixedNumericArray.join(); // '80,9,700,40,1,5,200'
mixedNumericArray.sort(); // [1, 200, 40, 5, '700', '80', '9']
mixedNumericArray.sort(compareNumbers); // [1, 5, '9', 40, '80', 200, '700']
Метод sort()
повертає посилання на початковий масив, тому зміни, внесені до повернутого масиву, також змінять початковий масив.
const numbers = [3, 1, 4, 1, 5];
const sorted = numbers.sort((a, b) => a - b);
// numbers і sorted - це обидва [1, 1, 3, 4, 5]
sorted[0] = 10;
console.log(numbers[0]); // 10
Використання sort()
на розріджених масивах. Порожні слоти переміщуються до кінця масиву.
console.log(["a", "c", , "b"].sort()); // ['a', 'b', 'c', empty]
console.log([, undefined, "a", "b"].sort()); // ["a", "b", undefined, empty]
Виклик sort()
на об'єктах, які не є масивами.
const arrayLike = {
length: 3,
unrelated: "foo",
0: 5,
2: 4,
};
console.log(Array.prototype.sort.call(arrayLike));
// { '0': 4, '1': 5, length: 3, unrelated: 'foo' }
Для сортування рядків з нелатинськими символами, наприклад, рядків з акцентованими символами (e, é, è, a, ä тощо) або рядків інших мов, використовуйте метод String.prototype.localeCompare()
. Ця функція може порівнювати такі символи так, що вони з'являються в правильному порядку.
const items = ["réservé", "premier", "communiqué", "café", "adieu", "éclair"];
items.sort((a, b) => a.localeCompare(b));
// items is ['adieu', 'café', 'communiqué', 'éclair', 'premier', 'réservé']