Как отсортировать массив объектов в javascript

Как отсортировать массив объектов в javascript

При работе с массивами объектов в JavaScript часто возникает задача упорядочивания по одному или нескольким полям. Метод Array.prototype.sort() позволяет реализовать сортировку с учётом структуры объектов, но требует точного задания логики сравнения.

Если нужно отсортировать массив по числовому значению, например, по полю age, используется функция сравнения: arr.sort((a, b) => a.age - b.age). Для строковых полей лучше применять localeCompare для корректной сортировки с учётом регистра и локали: arr.sort((a, b) => a.name.localeCompare(b.name)).

Многокритериальная сортировка реализуется последовательными сравнениями: если первое поле одинаковое, проверяется второе. Например: arr.sort((a, b) => a.age - b.age || a.name.localeCompare(b.name)). Такой подход особенно полезен при сортировке данных с повторами по основному ключу.

Важно учитывать, что метод sort изменяет исходный массив. Если требуется сохранить оригинальные данные, нужно работать с копией: [...arr].sort(...). Это особенно актуально при работе с состоянием в React или других фреймворках, где иммутабельность играет важную роль.

Как отсортировать массив объектов по числовому полю

Как отсортировать массив объектов по числовому полю

Для сортировки массива объектов по числовому полю используется метод sort() с функцией сравнения. Пример:

const data = [
{ name: "А", value: 10 },
{ name: "Б", value: 5 },
{ name: "В", value: 20 }
];
data.sort((a, b) => a.value - b.value);

Результат: объекты будут упорядочены по возрастанию поля value. Для обратного порядка достаточно поменять местами a и b>:

data.sort((a, b) => b.value - a.value);

Функция сравнения должна возвращать:

  • отрицательное число, если a должно быть перед b;
  • нулевое значение – если порядок неважен;
  • положительное – если a должно быть после b.

Если поле может быть нечисловым или отсутствовать, требуется дополнительная проверка:

data.sort((a, b) => {
const av = typeof a.value === "number" ? a.value : 0;
const bv = typeof b.value === "number" ? b.value : 0;
return av - bv;
});

Для сохранения исходного массива можно использовать slice() перед сортировкой:

Для сохранения исходного массива можно использовать undefinedslice()</strong> перед сортировкой:»></p>
<pre><code>const sorted = data.slice().sort((a, b) => a.value - b.value);
</code></pre>
<h2>Сортировка по строковому полю с учётом регистра</h2>
<p><img decoding=

При сортировке массива объектов по строковому полю с учётом регистра используется метод sort() с функцией сравнения, учитывающей кодовые точки символов. Это означает, что заглавные буквы будут располагаться перед строчными из-за их меньших значений в таблице Unicode.

Пример:

const users = [
{ name: "Анна" },
{ name: "юрий" },
{ name: "Борис" },
{ name: "алексей" }
];
users.sort((a, b) => a.name.localeCompare(b.name));

Результат сортировки:

[
{ name: "Анна" },
{ name: "Борис" },
{ name: "алексей" },
{ name: "юрий" }
]

Функция localeCompare() без параметров сохраняет чувствительность к регистру. Если регистр не должен влиять на порядок, используется опция sensitivity: 'base':

users.sort((a, b) => a.name.localeCompare(b.name, 'ru', { sensitivity: 'base' }));

Для строго регистрозависимой сортировки предпочтительно использовать сравнение напрямую через String.prototype.localeCompare, без преобразования регистра с помощью toLowerCase() или toUpperCase(), так как это может исказить порядок символов в языках с нестандартным алфавитом.

Сортировка по дате в формате ISO и локальном формате

Сортировка по дате в формате ISO и локальном формате

При работе с датами в ISO-формате (например, «2025-05-03T14:30:00Z») сортировка выполняется корректно при использовании localeCompare или стандартного сравнения строк. Формат ISO упорядочен по убыванию значимости компонентов, что позволяет сортировать такие строки напрямую.

Пример сортировки массива объектов с ISO-датами:

const data = [
{ name: "A", date: "2025-05-03T14:30:00Z" },
{ name: "B", date: "2023-11-22T09:00:00Z" }
];
data.sort((a, b) => a.date.localeCompare(b.date));
// Или с Date:
// data.sort((a, b) => new Date(a.date) - new Date(b.date));

Локальные форматы (например, «03.05.2025» или «03/05/2025») требуют преобразования в объект Date. Такие строки не поддерживают прямое сравнение. Использование new Date() может дать неверный результат из-за неоднозначности формата. Рекомендуется предварительно парсить значения вручную или использовать библиотеку, например date-fns или Luxon.

Пример с ручным преобразованием локального формата «дд.мм.гггг»:

const data = [
{ name: "A", date: "03.05.2025" },
{ name: "B", date: "22.11.2023" }
];
function parseDate(str) {
const [day, month, year] = str.split(".");
return new Date(${year}-${month}-${day});
}
data.sort((a, b) => parseDate(a.date) - parseDate(b.date));

При наличии смешанных форматов все значения необходимо привести к унифицированному виду до сортировки. Несогласованность форматов приводит к некорректному порядку. Использование Intl.DateTimeFormat подходит для отображения, но не для сравнения дат.

Сортировка массива объектов по вложенному свойству

Сортировка массива объектов по вложенному свойству

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

const data = [
{ user: { name: 'Иван', age: 30 } },
{ user: { name: 'Ольга', age: 25 } },
{ user: { name: 'Пётр', age: 35 } }
];

Сортировка по возрасту во вложенном свойстве user.age выглядит так:

data.sort((a, b) => a.user.age - b.user.age);

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

data.sort((a, b) => {
const ageA = a.user?.age ?? 0;
const ageB = b.user?.age ?? 0;
return ageA - ageB;
});

Для строк применяется метод localeCompare:

data.sort((a, b) => a.user.name.localeCompare(b.user.name));

Если вложенность глубже, например user.profile.details.age, обращение усложняется:

data.sort((a, b) => {
const ageA = a.user?.profile?.details?.age ?? 0;
const ageB = b.user?.profile?.details?.age ?? 0;
return ageA - ageB;
});

Для сортировки по нескольким вложенным уровням можно использовать вспомогательную функцию:

function getNestedValue(obj, path) {
return path.split('.').reduce((acc, key) => acc?.[key], obj);
}
data.sort((a, b) => {
const valA = getNestedValue(a, 'user.profile.details.age') ?? 0;
const valB = getNestedValue(b, 'user.profile.details.age') ?? 0;
return valA - valB;
});

Такой подход снижает дублирование и упрощает работу с динамическими путями вложенности.

Как отсортировать по нескольким полям одновременно

Как отсортировать по нескольким полям одновременно

Для сортировки массива объектов по нескольким критериям используется метод sort() с функцией сравнения, в которой при равенстве одного поля происходит сравнение по следующему.

Пример: имеется массив пользователей, каждый с полями age и name.

const users = [
{ name: 'Анна', age: 25 },
{ name: 'Иван', age: 20 },
{ name: 'Анна', age: 20 },
{ name: 'Борис', age: 25 }
];
users.sort((a, b) => {
if (a.name < b.name) return -1;
if (a.name > b.name) return 1;
return a.age - b.age;
});

Сначала сортировка идёт по name в алфавитном порядке. При равных именах сравнивается age. В случае чисел – прямое вычитание, для строк – сравнение с помощью операторов < и >.

Для обратного порядка чисел поменяйте знак: b.age - a.age. Для строк используйте localeCompare():

users.sort((a, b) => {
const nameCompare = a.name.localeCompare(b.name);
if (nameCompare !== 0) return nameCompare;
return b.age - a.age;
});

Если критериев больше двух, используйте цепочку if или массив правил:

const rules = [
{ key: 'city', direction: 'asc' },
{ key: 'age', direction: 'desc' },
{ key: 'name', direction: 'asc' }
];
array.sort((a, b) => {
for (const rule of rules) {
const { key, direction } = rule;
const valA = a[key];
const valB = b[key];
if (valA === valB) continue;
const compare = typeof valA === 'string'
? valA.localeCompare(valB)
: valA - valB;
return direction === 'asc' ? compare : -compare;
}
return 0;
});

Такой способ позволяет масштабировать сортировку без дублирования кода.

Что делать, если поле может быть null или undefined

Что делать, если поле может быть null или undefined

При сортировке массива объектов в JavaScript часто приходится работать с полями, которые могут быть равны null или undefined. Это может привести к неожиданным результатам, если не обработать такие значения корректно. Рассмотрим несколько способов работы с такими случаями.

  • Использование оператора nullish coalescing (??): Этот оператор позволяет задать значение по умолчанию для переменной, если она равна null или undefined. Пример:
const sortedArray = array.sort((a, b) => (a.field ?? 0) - (b.field ?? 0));

Здесь, если a.field или b.field равны null или undefined, используется значение 0.

  • Проверка на null или undefined: Можно явно проверять значения и перед сортировкой заменять их на нужное значение.
const sortedArray = array.sort((a, b) => {
const valA = a.field == null ? 0 : a.field;
const valB = b.field == null ? 0 : b.field;
return valA - valB;
});

В этом примере проверяется, равно ли значение a.field или b.field null или undefined. Если да, то заменяется на 0.

  • Использование функции сортировки с условием: Можно использовать более сложную логику для обработки различных типов значений (например, строки, числа или null).
const sortedArray = array.sort((a, b) => {
if (a.field == null) return 1; // Перемещаем null/undefined в конец
if (b.field == null) return -1;
return a.field - b.field; // Числовая сортировка
});

Здесь значение null или undefined перемещается в конец массива.

  • Использование сторонних библиотек: В некоторых случаях можно использовать библиотеки, такие как Lodash, которые обеспечивают более гибкие функции сортировки с учетом null или undefined.
const sortedArray = _.sortBy(array, item => item.field ?? 0);

В этой строке используется Lodash для сортировки массива с заменой значений null и undefined на 0.

Вопрос-ответ:

Ссылка на основную публикацию