Marcel Kredzel
Marcel Kredzel

Reputation: 45

Merge objects of an array into one object by key

I am trying to merge objects of an array into one if they have the same key.

Having this array:

let data = [
  { id: "1", cars: 5 }, 
  { id: "1", pasta: 2 },
  { id: "2", cars: 0 }, 
  { id: "2", pasta: 0 },
];

I would like to achieve this:

let data = [
  { id: "1", cars: 5, pasta: 2 },
  { id: "2", cars: 0, pasta: 0 },
];

I am looking for any solutions, but preferable ES6.

Upvotes: 0

Views: 54

Answers (2)

Matias Kinnunen
Matias Kinnunen

Reputation: 8540

Using Array.prototype.reduce():

let data = [
  { id: "1", cars: 5 }, 
  { id: "1", pasta: 2 },
  { id: "2", cars: 0 }, 
  { id: "2", pasta: 0 },
]

const result = data.reduce((items, item) => {
  const existingItem = items.find(({ id }) => id === item.id)

  if (existingItem) Object.assign(existingItem, item)
  else items.push({ ...item })

  return items
}, [])

console.log(result)

// Original array is left intact:
console.log(data)

Upvotes: 0

Nick
Nick

Reputation: 16576

Here's a solution that combines the Array reduce method and the Object values method. One benefit of this approach is that it is O(n) time complexity, which would only really matter if you had a ton of data, but still potentially more efficient than the solutions that include loops inside loops.

let data = [
  { id: "1", cars: 5 }, 
  { id: "1", pasta: 2 },
  { id: "2", cars: 0 }, 
  { id: "2", pasta: 0 },
];

const combined = Object.values(data.reduce((acc, el) => {
  acc[el.id] = { ...acc[el.id], ...el };
  return acc;
}, {}));

console.log(combined);

Upvotes: 1

Related Questions