-1

How do I modify an array of objects so that duplicate names are merged. Consider the example

const arr1 = [
   {name: "HTML", count: 4},
   {name: "CSS", count: 5}, 
   {name: "JS", count: 10}, 
   {name: "CSS", count: 11},
   {name: "PHP", count: 12},
   {name: "HTML", count: 4},
   {name: "CSS", count: 14},
   {name: "JS", count: 7}]

My resulting array should be

const result = [
   {name: "HTML", count: 8},
   {name: "CSS", count: 30}, 
   {name: "JS", count: 17}, 
   {name: "PHP", count: 12}]

In this case, the count property gets added for objects having same name.

Can someone please tell how I can do this
(I would also like to have an explanation for the code because I am a bit new to using higher order functions) Any help is appreciated, Thanks

3 Answers3

1

You could combine the use of reduce, Object.entries and map

Approach: make an lookup object with key-value pairs of name and total count, calculate this object by using reduce. Then use Object.entries to transform the object to array of key-value pairs, map through each of the pair and return the related object

const arr1 = [
  { name: "HTML", count: 4 },
  { name: "CSS", count: 5 },
  { name: "JS", count: 10 },
  { name: "CSS", count: 11 },
  { name: "PHP", count: 12 },
  { name: "HTML", count: 4 },
  { name: "CSS", count: 14 },
  { name: "JS", count: 7 },
]

const res = Object.entries(
  arr1.reduce(
    (acc, el) => ({ ...acc, [el.name]: (acc[el.name] || 0) + el.count }),
    {}
  )
).map(([name, count]) => ({ name, count }))

console.log(res)
.as-console-wrapper { max-height: 100% !important; }
hgb123
  • 13,869
  • 3
  • 20
  • 38
1

You can merge the object with the same keys by using Arary.prototype.reduce, create a map of name as key and the count as value.

If the name exists in the map, add the count else inset a new entry, then map to a array of object of the form {name: <name>, count: <count>} using Object.keys and Array.prototype.map :

const arr1 = [{name: "HTML", count: 4}, {name: "CSS", count: 5},{name: "JS", count: 10}, {name: "CSS", count: 11}, {name: "PHP", count: 12}, {name: "HTML", count: 4}, {name: "CSS", count: 14}, {name: "JS", count: 7}];
   
const merged = arr1.reduce((acc, {name, count}) => {
  return {...acc, [name]: (acc[name] ?? 0) + count } ;
}, {})

const arr = Object.keys(merged)
  .map(key => ({
    name: key,
    count: merged[key]
  }));

console.log(arr);
Fullstack Guy
  • 16,368
  • 3
  • 29
  • 44
1

This will give the desired result:

resultArr = [];
for(let arrObj of arr1) {
    var index = resultArr.findIndex(resultObj => resultObj.name == arrObj.name)
    if(index == -1) {
        resultArr.push(arrObj);
    }
    else {
        resultArr[index].count += arrObj.count;
    }
}
aRvi
  • 2,203
  • 1
  • 14
  • 30