In array of objects group items by common property

Viewed 82

I have two large arrays, one of items, the other of names who have the items. I need to push all the names who have the matching items into array2 items.

I can do this via a nest forEach loop:

array1 = [
  {item: "1", name: "Joe" },
  {item: "2", name: "Sam" },
  {item: "1", name: "Alice"},
  {item: "3", name: "Peter"},
  {item: "1", name: "Jack"},
]

array2 = [
  { item: "1", names: []},
  { item: "2", names: []},
  { item: "3", names: []},
]

array2.forEach(x => {
    array1.forEach(y => {
        if( x.item === y.item ){
        x.names.push(y.name)
        }
    })
})
console.log(array2)

But I have a sense this is bad practice and not to mention resource heavy on large arrays.

What is the moden way to do this?

2 Answers

I believe, you'd be much better off taking advantage of Map:

const src = [
        {item: "1", name: "Joe" },
        {item: "2", name: "Sam" },
        {item: "1", name: "Alice"},
        {item: "3", name: "Peter"},
        {item: "1", name: "Jack"},
      ],
      
      result = [...src
        .reduce((acc, {item,name}) => {
          const group = acc.get(item)
          group
            ? group.names.push(name)
            : acc.set(item, {item, names:[name]})
          return acc
        }, new Map)
        .values()
      ]
      
console.log(result)      

array2.forEach(a2 => { 
     let names = array1.filter(a1 => a1.item === a2.item)
                       ?.map(n => n.name); 
     a2.names = names ?? []; 
});
Related