0

I have an object that contains duplicate id properties and I want to reduce them to one array for each. I only figured out a way to find unique ids, but how can I concat the name attribute?

const x = [
   {id: 1, name: 'green'},
   {id: 2, name: 'red'},
   {id: 1, name: 'blue'}
]

Desired result:

[
   {id: 1, name: 'green, blue'},
   {id: 2, name: 'red'}
]
9pfs
  • 560
  • 5
  • 17
Dorbn
  • 277
  • 4
  • 11

3 Answers3

1

Simple reduce to combine and using Object.values to get the result you are after.

const x = [{
    id: 1,
    name: 'green'
  },
  {
    id: 2,
    name: 'red'
  },
  {
    id: 1,
    name: 'blue'
  }
]

const result = Object.values(x.reduce((acc, obj) => {
  if (acc[obj.id]) {
    acc[obj.id].name += ", " + obj.name;
  } else {
    acc[obj.id] = { ...obj
    };
  }
  return acc;
}, {}));

console.log(result);
epascarello
  • 204,599
  • 20
  • 195
  • 236
1
  1. Iterate over x using .reduce while using a Map to store id as key and the array element as the value
  2. If the map already has a record with this id, just concatenate the name to it
  3. Otherwise, add a new record to it
  4. In the end, the values of the map will contain all the array elements grouped by the id and having the name to include all of them.

const x = [ { id: 1, name: 'green' }, { id: 2, name: 'red' }, { id: 1, name: 'blue' }
];

const res = [...x.reduce((map, {id, name}) => {
  if(map.has(id)) map.get(id).name += `, ${name}`;
  else map.set(id, { id, name });
  return map;
}, new Map)
.values()
];

console.log(res);
Majed Badawi
  • 27,616
  • 4
  • 25
  • 48
1

Simple solution using Set to get a list of unique ids.

Then, using filter and map we get all the matching objects, and join the names together.

const x = [
   {id: 1, name: 'green'},
   {id: 2, name: 'red'},
   {id: 1, name: 'blue'}
]

const result = [];
const uniqueIds = [...new Set(x.map(item => item.id))];
const merged = uniqueIds.forEach((id) => {
  
  // Matching ids
  const match = x.filter((o) => o.id === id);
  
  // Names of matching ids
  const names =  match.map(x => x.name);
  
  // Add new
  result.push({
    id,
    names: names.join(', ')
  });
});

console.log(result);
0stone0
  • 34,288
  • 4
  • 39
  • 64