Merge objects with same key in javascript

情到浓时终转凉″ 提交于 2019-12-05 01:34:33

问题


I have been trying to figure this out for a long time, if i have an array of objects like so:

var my_array = [
    Object {Project: A, Hours: 2},
    Object {Project: B, Hours: 3},
    Object {Project: C, Hours: 5},
    Object {Project: A, Hours: 6},
    Object {Project: C, Hours: 9}
]

I want to merge all the objects with the same key together into one object, such that their hours get added up:

Expected output:

my_array = [
    Object {Project: A, Hours: 8}
    Object {Project: B, Hours: 3}
    Object {Project: C, Hours: 14}
]

How can I approach this issue? It has taken me a long time to get my data formatted in this way, this is the last step!

My attempt, I get that I am looping through array, not sure how to deal with the merging of the objects:

for (var i =0; i<my_array.length; i++) {
   my_array[i].Project   // access the object project key
   my_array[i].Hours     // need to increment hours
}

回答1:


In your attempt, you are missing out on creating a new array

var newArray = [];
var uniqueprojects = {};
for (var i =0; i<my_array.length; i++) {

   if ( !uniqueproject[my_array[i].Project] )
   {
     uniqueproject[my_array[i].Project] = 0;
   }
   uniqueproject[my_array[i].Project] += my_array[i].Hours;
   //my_array[i].Project   // access the object project key
   //my_array[i].Hours     // need to increment hours
}

Now create the final output array out of uniqueproject map

newArray = Object.keys(uniqueproject).map(function(key){return {Project:key, Hours:uniqueproject[key]}});



回答2:


You create another object where you can actually group the projects and accumulate the corresponding hours, like this

var groups = my_array.reduce(function(resultObject, currentObject) {

    // if this is the first time the project appears in the array, use zero as the
    // default hours
    resultObject[currentObject.Project] = resultObject[currentObject.Project] || 0;

    // add the current hours corresponding to the project
    resultObject[currentObject.Project] += currentObject.Hours;

    return resultObject;
}, {});

At this point, your groups will look like this

console.log(groups);
// { A: 8, B: 3, C: 14 }

Now, you just have to expand this object, like this

var result = Object.keys(groups).map(function(currentGroup) {
    return {Project: currentGroup, Hours: groups[currentGroup]};
});

Now, the result will be

[ { Project: 'A', Hours: 8 },
  { Project: 'B', Hours: 3 },
  { Project: 'C', Hours: 14 } ]



回答3:


Both thefourtheye's and gurvinder372's proposed solutions work, so I set up a benchmark test on jsPerf to test which is faster. You can see it here.

It appears that gurvinder372's code is by far the fastest.

P.S. please ignore the Uncaught TypeError as it is a jsPerf issue currently being fixed that has nothing to do with the results of the test. For more info, see this and this.



来源:https://stackoverflow.com/questions/36147321/merge-objects-with-same-key-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!