JavaScript Object.groupBy: сгруппировать массив
Object.groupBy() группирует элементы массива по ключу, который возвращает callback, и сразу собирает объект с массивами. Метод появился в ES2024 и заменяет ручной цикл с проверкой result[key] ||= []. В отличие от reduce, он не требует начального значения и явно сообщает намерение.
Сгруппировать заказы по статусу
const orders = [
{id: 1, status: "paid", total: 1200},
{id: 2, status: "new", total: 800},
{id: 3, status: "paid", total: 450},
];
const byStatus = Object.groupBy(orders, (order) => order.status);
console.log(Object.keys(byStatus).join(",")); // paid,new
console.log(byStatus.paid.length); // 2
console.log(Object.getPrototypeOf(byStatus)); // nullCallback получает элемент и его индекс. Ключ приводится к строке или символу, поэтому число 1 станет ключом "1". Порядок ключей соответствует первому появлению группы, а порядок элементов внутри группы — исходному массиву.
Результат — объект с null в прототипе. У него нет метода hasOwnProperty, поэтому проверяйте наличие через Object.hasOwn(byStatus, "paid"). Зато ключ __proto__ не портит прототип и не создаёт неожиданное наследование.
Использовать объект как ключ
const core = {name: "core"};
const web = {name: "web"};
const users = [
{id: 1, team: core},
{id: 2, team: web},
{id: 3, team: core},
];
const byTeam = Map.groupBy(users, (user) => user.team);
console.log(byTeam.get(core).map((user) => user.id).join(",")); // 1,3Map.groupBy() хранит ключи по ссылке, а не приводит их к строке. Берите его, если группируете по объектам, датам или другим значениям, для которых важна идентичность. Для строковых ключей достаточно Object.groupBy().
Метод поддерживается в Chrome 117+, Firefox 119+, Safari 17.4+ и Node.js 21+. В старых окружениях нужен полифил или reduce. Группировка не копирует элементы: массивы содержат те же ссылки на объекты, поэтому изменение элемента отразится в исходном массиве.
Документация: Object.groupBy, Map.groupBy.