Как отсортировать массив объектов по дате в JavaScript
Что проверяют
Знаете ли вы, как работает sort с компаратором, что он мутирует массив и как JavaScript разбирает даты. Следом обычно спрашивают про формат вроде «15.10.2023», про записи без даты и про сортировку большого массива.
Как отвечать
Базовое решение:
const sorted = events.toSorted(
(a, b) => Date.parse(a.date) - Date.parse(b.date)
);Для убывания поменяйте a и b местами. Дальше раскройте детали:
- мутация:
sort()сортирует исходный массив на месте и возвращает ссылку на него же. В React это ломает состояние, поэтому нуженtoSorted()из ES2023, он есть во всех актуальных браузерах, или копия[...events].sort(...); - компаратор: должен вернуть отрицательное число, ноль или положительное. Без компаратора элементы сравниваются как строки;
- ISO-строки: даты вида
2023-10-15можно сравнивать как строки черезlocaleCompare, лексикографический порядок совпадает с хронологическим. Для15.10.2023это не работает; - разбор дат:
Date.parseгарантированно понимает только формат ISO. Строка из одной даты трактуется как UTC, а дата со временем без зоны как локальное время. Другие форматы разбирайте явно или через date-fns и Day.js; - невалидные значения:
Date.parseвернётNaN, а компаратор сNaNдаёт непредсказуемый порядок. Такие записи отправляйте в конец явной проверкой; - производительность: компаратор вызывается O(n log n) раз и каждый раз парсит строки. На больших массивах один раз посчитайте метку времени для каждого элемента и сортируйте по ней;
- стабильность: с ES2019
sortстабилен, элементы с одинаковой датой сохраняют исходный порядок.
Где спотыкаются
Возвращают из компаратора логическое значение: (a, b) => a.date > b.date. Получаются только 1 и 0, отрицательного числа нет, и итоговый порядок зависит от алгоритма движка.
Сортируют массив из props или state на месте. React не видит нового массива, а тот же массив, отсортированный где-то ещё, неожиданно меняется.
Полагаются на new Date("15.10.2023"). Разбор нестандартных строк спецификацией не описан, результат различается между браузерами, и сортировка работает у разработчика, а у части пользователей нет.