← Все вопросы

Почему sort сортирует числа как строки и как отсортировать массив чисел в JavaScript?

Задан 16 месяцев назад1.3к просмотров2 ответа
11

Сортирую массив [10, 2, 1, 21] через .sort(), а получаю [1, 10, 2, 21] — какой-то бред. Почему sort сортирует числа неправильно и как отсортировать массив чисел по-человечески, по возрастанию?

2 ответа

15
✓ Принятый ответ — помог автору

Это классическая засада. По умолчанию sort() преобразует элементы в строки и сравнивает их посимвольно (лексикографически). Поэтому "10" идёт раньше "2" — потому что символ '1' меньше '2'.

const nums = [10, 2, 1, 21];
console.log(nums.sort()); // [1, 10, 2, 21] — как строки!

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

  • отрицательное число — если a идёт раньше b;
  • положительное — если позже;
  • ноль — если порядок не важен.
const nums = [10, 2, 1, 21];

// по возрастанию
nums.sort((a, b) => a - b);
console.log(nums); // [1, 2, 10, 21]

// по убыванию
nums.sort((a, b) => b - a);
console.log(nums); // [21, 10, 2, 1]

a - b работает, потому что разность сама даёт нужный знак.

Ещё две ловушки:

  1. sort меняет исходный массив (мутирует), а не возвращает копию. Если нужна копия — сначала [...nums].sort(...).
  2. Для строк по алфавиту дефолтный sort() подойдёт, но с кириллицей/регистром лучше localeCompare:
const words = ['банан', 'Арбуз', 'вишня'];
words.sort((a, b) => a.localeCompare(b, 'ru'));
6

Запомни как мантру: числа — всегда с компаратором (a, b) => a - b. Без него sort думает, что у тебя строки.

И помни про мутацию — вот частая ошибка:

const original = [3, 1, 2];
const sorted = original.sort((a, b) => a - b);
console.log(original); // [1, 2, 3] — тоже изменился!

Чтобы не трогать оригинал:

const sorted = [...original].sort((a, b) => a - b);

Ваш ответ

Войдите, чтобы ответить на вопрос.