Использование Reduce для выполнения операции с массивом иногда кажется немного ошеломляющим. почему кто-то решил написать вложенные циклы для создания новой структуры массива, а не использовать библиотеки, такие как lodash, подчеркивание и т. д. ответ прост: более низкая стоимость импорта. Если вы младший разработчик JS, использование библиотек может обеспечить быстрое и простое решение, но всегда полезно знать, как делать что-то в vanilla JS. с этим позволяет узнать Javascript уменьшить.

вот список студентов, и просьба сгруппировать их по указанному имени свойства,

const hogwartsStudents = [
  {
    name: 'Harry Potter',
    house: 'Gryffindor',
    patronus: 'stag',
    joined_hogwarts_at: '1991-09-01T04:45:28.125Z',
  },
  {
   name: 'Hermione Granger',
   house: 'Gryffindor',
   patronus: 'Otter',
   joined_hogwarts_at: '1991-09-01T01:12:00.125Z',
  },
  {
   name: 'Ronald Weasley',
   house: 'Gryffindor',
   patronus: 'Jack Russell terrier',
   joined_hogwarts_at: '1991-09-01T02:25:28.125Z',
  },
  {
   name: 'Tom Riddle',
   house: 'Slytherin',
   patronus: 'none',
   joined_hogwarts_at: '1938-09-01T04:45:28.125Z',
  },
  {
   name: 'James Potter',
   house: 'Gryffindor',
   patronus: 'stag',
   joined_hogwarts_at: '1971-09-01T02:45:28.125Z',
  },
  {
   name: 'Severus Snape',
   house: 'Slytherin',
   patronus: 'Doe',
   joined_hogwarts_at: '1971-09-01T01:45:28.125Z',
  },
];

это означает, что пользователь может вызвать функцию, предоставляющую объект данных и значение ключа, с которым они хотят сгруппировать свои данные. достаточно просто импортировать lodash и сделать это.

lodash.groupBy(hogwartsStudents,'house');

нет ничего плохого в быстром решении, но помните, что импорт lodash влияет на размер вашего пакета.

Вот как мы хотим, чтобы наш вывод выглядел

{ 
Gryffindor: [
  {
    name: 'Harry Potter',
    house: 'Gryffindor',
    patronus: 'stag',
    joined_hogwarts_at: '1991-09-01T04:45:28.125Z',
  },
  {
    name: 'Hermione Granger',
    house: 'Gryffindor',
    patronus: 'Otter',
    joined_hogwarts_at: '1991-09-01T01:12:00.125Z',
  },
  {
   name: 'Ronald Weasley',
   house: 'Gryffindor',
   patronus: 'Jack Russell terrier',
   joined_hogwarts_at: '1991-09-01T02:25:28.125Z',
  },
  {
   name: 'James Potter',
   house: 'Gryffindor',
   patronus: 'stag',
   joined_hogwarts_at: '1971-09-01T02:45:28.125Z',
  },
],
Slytherin: [
  {
    name: 'Tom Riddle',
    house: 'Slytherin',
    patronus: 'none',
    joined_hogwarts_at: '1938-09-01T04:45:28.125Z',
  },
  {
    name: 'Severus Snape',
    house: 'Slytherin',
    patronus: 'Doe',
    joined_hogwarts_at: '1971-09-01T01:45:28.125Z',
  },
]}

Запачкаем руки методом массива Reduce.

function groupObjectArrayByProperty(objectArray, key) {
  if (!objectArray) return;
  let group = objectArray.reduce((acc, obj,index) => {
  let groupBy = obj[key];
  // Add object to list for given key's value
  acc[groupBy] = [...(acc[groupBy] || []), obj];
    return acc;
  }, {});
  
  return group;
}
groupObjectArrayByProperty(hogwartsStudents, 'house');

Здесь сокращение проходит через массив, выполняет операции над каждым элементом/объектом массива и уменьшает его до одного значения.

На первой итерации (индекс = 0):

акк = {}

obj = первый элемент `objectArray`

{
    name: 'Harry Potter',
    house: 'Gryffindor',
    patronus: 'stag',
    joined_hogwarts_at: '1991-09-01T04:45:28.125Z',
}

возвращенный элемент при уменьшении в аккумуляторе будет здесь, мы группируем по ключу «дом»:

{
 Gryffindor: [{
     name: 'Harry Potter',
     house: 'Gryffindor',
     patronus:'stag',
     joined_hogwarts_at: '1991-09-01T04:45:28.125Z'
 }]
}