Переместить повторяющееся свойство объекта в одно свойство в массиве объектов

#javascript

#javascript

Вопрос:

В основном у меня есть этот массив JavaScript:

 const a = [
  {name: 'Foo', place: 'US', age: 15},
  {name: 'Foo', place: 'UK', age: 21},
  {name: 'Bar', place: 'Canada', age: 20},
  {name: 'Bar', place: 'China', age: 22}
];
  

Каков самый быстрый способ сделать так, чтобы это выглядело так? (Где имя становится одним свойством объекта в массиве «a»). Как бы я повторил массив?

 const a = [
  {
    name: 'Foo',
    data: [
      {
        place: 'US', age: 15
      },
      {
        place: 'UK', age: 21
      }
    ]
  },
  {
    name: 'Bar',
    data: [
      {
        place: 'Canada', age: 20
      },
      {
        place: 'China', age: 22
      }
    ]
  }
];
  

Спасибо!

Комментарии:

1. Этот вопрос не является дубликатом вашего вопроса. В вашем вопросе вам нужен вывод массива, тогда как дублированный создает объект.

Ответ №1:

Вы можете использовать reduce функцию для группировки данных на основе name свойства, а затем взять Object.values .

 var a = [
  {name: 'Foo', place: 'US', age: 15},
  {name: 'Foo', place: 'UK', age: 21},
  {name: 'Bar', place: 'Canada', age: 20},
  {name: 'Bar', place: 'China', age: 22}
];

var result = Object.values(a.reduce((acc, {name, ...rest})=>{
    acc[name] = acc[name] || {name, data:[]};
    acc[name].data = [...acc[name].data, rest];
    return acc;
},{}));

console.log(result);  

Ответ №2:

Одним из способов может быть использование карты ES6. Вы можете использовать .reduce() для накопления объектов в a на карте. Каждый name может быть ключом на карте, и каждое значение на карте будет массивом объектов, которые имеют этот ключ в качестве name . После того, как вы создали Map , вы можете использовать Array.from() для преобразования карты в массив, одновременно предоставляя функцию отображения для преобразования записей [name, data[]] в объекты, пока происходит преобразование карты в массив.

Смотрите пример ниже:

 const a = [
  {name: 'Foo', place: 'US', age: 15},
  {name: 'Foo', place: 'UK', age: 21},
  {name: 'Bar', place: 'Canada', age: 20},
  {name: 'Bar', place: 'China', age: 22}
];

const res = Array.from(a.reduce((m, {name, ...r}) => {
  return m.set(name, (m.get(name) || []).concat(r));
}, new Map), ([name, data]) => ({name, data}));

console.log(res);