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

#javascript #arrays

#javascript #массивы

Вопрос:

У меня есть массив заказов ниже, и я хотел бы сконденсировать его по имени, а затем получить массив всех предметов, которые заказал пользователь

 const orders = [
  { name: 'Tedd', item: 'coke', },
  { name: 'Louise', item: 'burger' },
  { name: 'Louise', item: 'chips' },
  { name: 'David', item: 'chips' },
  { name: 'David', item: 'burger' },
  { name: 'David', item: 'coke' }
]
 

как я хочу, чтобы это выглядело

 [
  { name: 'Tedd', item: ['coke'] },
  { name: 'Louise', item: ['burger', 'chips'] },
  { name: 'David', item: ['chips', 'burger', 'coke'] }
]
 

Я попробовал это

       const out = [...new Set(orders.map(i => i.name))].map(i => {
        return { name: i, item: orders.reduce((a, b) => [a.item].concat([b.item])) }
      })
 

но он просто объединяет все заказы

 [
  { name: 'Tedd', item: ['chips', 'burger', 'coke'] },
  { name: 'Louise', item: ['chips', 'burger', 'coke'] },
  { name: 'David', item: ['chips', 'burger', 'coke'] }
]
 

Ответ №1:

сокращение может быть полезно для этой конкретной проблемы.

 orders.reduce((acc, curr) => {
    const personIndex = acc.findIndex((item) => item.name === curr.name);
    if (personIndex === -1) {
      acc.push({ name: curr.name, item: [curr.item] });
    } else {
      acc[personIndex].item.push(curr.item);
    }
    return acc;
  }, []);
 

Ответ №2:

Уменьшите массив до объекта с именем в качестве ключа и собранными элементами в качестве значений, затем запустите сопоставление ключей объекта, чтобы вернуть требуемый массив.

 const obj = orders.reduce((map, order) => {
const { name } = order;
if (map[name]) {
  map[name].push(order.item);
} else {
  map[name] = [order.item];
}
return map}, {})
const output = Object.keys(obj).map(key => ({name:key,item:obj[key]}))
console.log(output)
 

Ответ №3:

Используйте forEach и создайте объект. Если существует то же имя, что и ключ, нажмите на существующий массив. Получить Object.values из этого объекта сборки.

 const condence = arr => {
  const all = {};
  arr.forEach(({name, item}) => {
    all[name] ||= {name, item: []};
    all[name].item.push(item);
  })
  return Object.values(all);
}

const orders = [
  { name: 'Tedd', item: 'coke', },
  { name: 'Louise', item: 'burger' },
  { name: 'Louise', item: 'chips' },
  { name: 'David', item: 'chips' },
  { name: 'David', item: 'burger' },
  { name: 'David', item: 'coke' }
]

console.log(condence(orders))