Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Как сгруппировать массив по полю

Короткий ответ

Object.groupBy() принимает функцию, которая возвращает имя группы, и строит объект из массивов:

const products = [
  { title: 'Tea', category: 'drinks' },
  { title: 'Bread', category: 'food' },
  { title: 'Coffee', category: 'drinks' },
];
const groups = Object.groupBy(products, (product) => product.category);
 
console.log(groups.drinks.map((p) => p.title).join(', '));
console.log(Object.keys(groups).join(', '));

Результат:

Tea, Coffee
drinks, food

Через reduce

В старых средах соберите такой же объект через reduce():

const products = [
  { title: 'Tea', category: 'drinks' },
  { title: 'Bread', category: 'food' },
  { title: 'Coffee', category: 'drinks' },
];
const groups = products.reduce((result, product) => {
  (result[product.category] ??= []).push(product.title);
  return result;
}, {});
 
console.log(JSON.stringify(groups));

Результат:

{"drinks":["Tea","Coffee"],"food":["Bread"]}

По вычисленному значению

Группой может быть что угодно, что вернёт функция, например диапазон возрастов:

const ages = [12, 25, 17, 40, 8];
const groups = Object.groupBy(ages, (age) => (age < 18 ? 'children' : 'adults'));
 
console.log(groups.children.join(', '), '|', groups.adults.join(', '));

Результат:

12, 17, 8 | 25, 40

Частая ошибка

У результата Object.groupBy() нет прототипа, поэтому методов вроде hasOwnProperty() у него нет. Используйте Object.hasOwn() или оператор in:

const groups = Object.groupBy([1, 2, 3], (n) => (n % 2 ? 'odd' : 'even'));
 
console.log(typeof groups.hasOwnProperty);
console.log(Object.hasOwn(groups, 'odd'));

Результат:

undefined
true

Функции из этого ответа

  • Object.groupBy — Группирует элементы массива по ключу.
  • Array.prototype.reduce — Сводит массив к одному значению.
  • Map.groupBy — Группирует элементы в Map по любому ключу.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.