如何合并两个对象数组,并在JavaScript中求和重复对象键的值?

时间:2021-06-18 12:20:13

So, I have an indeterminate amount of arrays in an object, and I need to merge the objects in them. The arrays are guaranteed to be the same length, and the objects are guaranteed to have the same keys.

因此,我在一个对象中有一个不确定的数组,我需要合并它们中的对象。数组的长度保证相同,对象的键值保证相同。

I've tried iterating through it, though for some reason, it sums the objects in every key in the array.

我尝试遍历它,不过出于某种原因,它将数组中的每个键的对象都进行了汇总。

Example:

例子:

var demo = {
  "key1": [{"a": 4, "b": 3, "c": 2, "d": 1}, {"a": 2, "b": 3, "c": 4, "d": 5}, {"a": 1, "b": 4, "c": 2, "d": 9}]
  "key2": [{"a": 3, "b": 5, "c": 3, "d": 4}, {"a": 2, "b": 9, "c": 1, "d": 3}, {"a": 2, "b": 2, "c": 2, "d": 3}]
};

mergeArrays(demo);

/* Returns:
  {
    "arbitraryname": [{"a": 7, "b": 8, "c": 5, "d": 5}, {"a": 4, "b": 12, "c": 5, "d": 8}, {"a": 3, "b": 6, "c": 4, "d": 12}]
  }
*/

My current implementation attempts to do something like this:

我目前的实现尝试做以下事情:

var skeleton = {
  "a": 0,
  "b": 0,
  "c": 0,
  "d": 0
};

function mergeArrays = function (obj) {
  var flat = {};
  var keys = _.keys(prod);
  var len = obj[keys[0]].length;
  flat["arbitraryname"] = [];
  for (var i = 0; i < len; i++) {
    flat["arbitraryname"].push(skeleton);
  }
  flat["arbitraryname"].forEach(function (v, k) {
    _.forIn(v, function (key, value) {
      flat["arbitraryname"][k][key] += value;
    });
  });
  return flat;
}

Is there any easier way to do that? It also appears to return an array right now that's entirely identical. E.g.:

有更简单的方法吗?它现在还返回一个完全相同的数组。例如:

[{"a": 14, "b": 26, "c": 14, "d": 25}, {"a": 14, "b": 26, "c": 14, "d": 25}, {"a": 14, "b": 26, "c": 14, "d": 25}]

Where each object is a sum of ALL elements in the array. What am I doing wrong? Is there an easier way?

其中每个对象是数组中所有元素的总和。我做错了什么?有更简单的方法吗?

2 个解决方案

#1


3  

The following matches the commented array at top of question. Expected results are a little unclear

以下是在问题顶部的注释数组。预期的结果有点不明朗

Using Object.keys() makes it fairly easy.

使用Object.keys()使其相当容易。

var demo = {
    "key1": [{"a": 4, "b": 3, "c": 2, "d": 1}, {"a": 2, "b": 3, "c": 4, "d": 5}, {"a": 1, "b": 4, "c": 2, "d": 9}],
    "key2": [{"a": 3, "b": 5, "c": 3, "d": 4}, {"a": 2, "b": 9, "c": 1, "d": 3}, {"a": 2, "b": 2, "c": 2, "d": 3}]
};

// iterate and map using first array
var res = demo.key1.map(function(item, idx) { 
    //  loop over keys of each object in array and return 
    //  new objects with sums of matching index and keys
    return Object.keys(item).reduce(function(obj,key) {
        obj[key] = item[key] + demo.key2[idx][key];
        return obj;
    },{});  
});

// print "res" for demo
document.getElementById('pre').innerHTML =JSON.stringify(res, null, 4)
<pre id="pre"></pre>

#2


1  

I mean, you could just write it yourself - it's not overly complicated since your rules make it well-defined (plus vanilla is cross-browser compatible):

我的意思是,你可以自己写出来——它并不太复杂,因为你的规则让它定义得很明确(加上vanilla是跨浏览器兼容的):

var resultArray = [];

for(var key in demo) {
  if(demo.hasOwnProperty(key)) {
    demo[key].forEach(function(obj, i) {
      if(!resultArray[i]) {
        resultArray[i] = {};
      }

      for(var letterKey in obj) {
        if(obj.hasOwnProperty(letterKey)) {
          if(resultArray[i][letterKey]) {
            resultArray[i][letterKey] += obj[letterKey];
          } else {
            resultArray[i][letterKey] = obj[letterKey];
          } 
        }
      }
    });
  }
}

That should work.

这应该工作。

#1


3  

The following matches the commented array at top of question. Expected results are a little unclear

以下是在问题顶部的注释数组。预期的结果有点不明朗

Using Object.keys() makes it fairly easy.

使用Object.keys()使其相当容易。

var demo = {
    "key1": [{"a": 4, "b": 3, "c": 2, "d": 1}, {"a": 2, "b": 3, "c": 4, "d": 5}, {"a": 1, "b": 4, "c": 2, "d": 9}],
    "key2": [{"a": 3, "b": 5, "c": 3, "d": 4}, {"a": 2, "b": 9, "c": 1, "d": 3}, {"a": 2, "b": 2, "c": 2, "d": 3}]
};

// iterate and map using first array
var res = demo.key1.map(function(item, idx) { 
    //  loop over keys of each object in array and return 
    //  new objects with sums of matching index and keys
    return Object.keys(item).reduce(function(obj,key) {
        obj[key] = item[key] + demo.key2[idx][key];
        return obj;
    },{});  
});

// print "res" for demo
document.getElementById('pre').innerHTML =JSON.stringify(res, null, 4)
<pre id="pre"></pre>

#2


1  

I mean, you could just write it yourself - it's not overly complicated since your rules make it well-defined (plus vanilla is cross-browser compatible):

我的意思是,你可以自己写出来——它并不太复杂,因为你的规则让它定义得很明确(加上vanilla是跨浏览器兼容的):

var resultArray = [];

for(var key in demo) {
  if(demo.hasOwnProperty(key)) {
    demo[key].forEach(function(obj, i) {
      if(!resultArray[i]) {
        resultArray[i] = {};
      }

      for(var letterKey in obj) {
        if(obj.hasOwnProperty(letterKey)) {
          if(resultArray[i][letterKey]) {
            resultArray[i][letterKey] += obj[letterKey];
          } else {
            resultArray[i][letterKey] = obj[letterKey];
          } 
        }
      }
    });
  }
}

That should work.

这应该工作。