简体   繁体   English

在javascript中使用相同的键合并对象

[英]Merge objects with same key in javascript

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
}

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 此时,您的groups将如下所示

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 } ]

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 现在从uniqueproject map创建最终输出数组

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

Both thefourtheye 's and gurvinder372 's proposed solutions work, so I set up a benchmark test on jsPerf to test which is faster. thefourtheyegurvinder372提出的解决方案都有效,所以我在jsPerf上设置了一个基准测试来测试哪个更快。 You can see it here . 你可以在这里看到它。

It appears that gurvinder372 's code is by far the fastest. 似乎gurvinder372的代码是迄今为止最快的代码。

PS 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. PS请忽略Uncaught TypeError因为它是一个当前正在修复的jsPerf问题,与测试结果无关。 For more info, see this and this . 欲了解更多信息,请参阅这个

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM