如何合并两个对象数组,并将JavaScript中重复的对象键的值相加?
How to merge two arrays of objects, and sum the values of duplicate object keys in JavaScript?
所以,我在一个对象中有不确定数量的数组,我需要合并其中的对象。数组保证长度相同,对象保证有相同的键。
我尝试遍历它,但出于某种原因,它对数组中每个键中的对象求和。
示例:
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}]
}
*/
我当前的实现尝试做这样的事情:
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;
}
有更简单的方法吗?现在 return 一个数组似乎也是完全相同的。例如:
[{"a": 14, "b": 26, "c": 14, "d": 25}, {"a": 14, "b": 26, "c": 14, "d": 25}, {"a": 14, "b": 26, "c": 14, "d": 25}]
其中每个对象都是数组中所有元素的总和。我究竟做错了什么?有没有更简单的方法?
以下匹配问题顶部的注释数组。预期结果有点不清楚
使用 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>
我的意思是,你可以自己写 - 它并不过分复杂,因为你的规则使它 well-defined(加上 vanilla 是 cross-browser 兼容):
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];
}
}
}
});
}
}
应该可以。
所以,我在一个对象中有不确定数量的数组,我需要合并其中的对象。数组保证长度相同,对象保证有相同的键。
我尝试遍历它,但出于某种原因,它对数组中每个键中的对象求和。
示例:
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}]
}
*/
我当前的实现尝试做这样的事情:
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;
}
有更简单的方法吗?现在 return 一个数组似乎也是完全相同的。例如:
[{"a": 14, "b": 26, "c": 14, "d": 25}, {"a": 14, "b": 26, "c": 14, "d": 25}, {"a": 14, "b": 26, "c": 14, "d": 25}]
其中每个对象都是数组中所有元素的总和。我究竟做错了什么?有没有更简单的方法?
以下匹配问题顶部的注释数组。预期结果有点不清楚
使用 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>
我的意思是,你可以自己写 - 它并不过分复杂,因为你的规则使它 well-defined(加上 vanilla 是 cross-browser 兼容):
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];
}
}
}
});
}
}
应该可以。