我有一个愚蠢的问题,起初似乎很容易解决,但结果却很棘手。
我有一个对象数组,每个对象都有两个属性:id和value:
[
{id: 2, value: 10},
{id: 4, value: 3},
{id: 2, value: 2},
{id: 1, value: 15}
]
我想编写一个算法来总结具有相似id的值的值。 我的最终结果应该是一个只包含合并对象的新数组:
[
{id: 2, value: 12},
{id: 4, value: 3},
{id: 1, value: 15}
]
我已尝试过以下操作,但它无法正常工作:
var arr = [];
arr.push({id: 2, visit:10});
arr.push({id: 4, visit:3});
arr.push({id: 2, visit:2});
arr.push({id: 1, visit:15});
// Deep copy
var copy = jQuery.extend(true, [], arr);
var masterArr = [];
for (var i = 0; i < arr.length; i++) {
var objArr = [];
objArr.push(arr[i]);
for (var j = copy.length-1; j > -1; j--) {
if (arr[i].id === copy[j].id) {
var q = copy.splice(j,1);
}
}
masterArr.push(objArr);
}
我的计划是首先在单独的数组(objArr)中收集所有类似的对象,将它们相加并将它们放在一个结束数组(masterArr)中。我使用jquerys extend来制作深层复制(不是参考)和反向迭代和拼接以删除已经找到的对象&#34;复制&#34;。
这不起作用!它似乎不是一个解决我的问题非常有效的方法。 我怎么能这样做?性能不是最优先考虑的事情,而是很好地拥有&#34;!
谢谢!
答案 0 :(得分:1)
// First group the data based on id and sum the values
var temp = data.reduce(function(result, current) {
result[current.id] = (result[current.id] || 0) + current.value;
return result;
}, {});
// then recreate the objects with proper id and value properties
var result = [];
for (var key in temp) {
result.push({
id: parseInt(key, 10),
value: temp[key]
});
}
console.log(result);
<强>输出强>
[ { id: 1, value: 15 },
{ id: 2, value: 12 },
{ id: 4, value: 3 } ]
答案 1 :(得分:1)
你可以这样做:
// Assuming:
a = [{id: 2, value: 10}, {id: 4, value: 3}, {id: 2, value: 2}, {id: 1, value: 15}]
var b = {}, // Temporary variable;
c = []; // This will contain the result;
// Build a id:value object ( {1: 15, 2: 12, 4: 3} )
a.map(function(current){b[current.id] = (b[current.id] || 0) + current.value});
for(var key in b){ // Form that into the desired output format.
c.push({id: parseInt(key, 10), value: b[key]});
}
console.log(c);
/* [{id: 1, value: 15},
{id: 2, value: 12},
{id: 4, value: 3}] */
我使用parseInt(key, 10)
,因为键是字符串,您可能希望它们再次转换为整数。
答案 2 :(得分:1)
最快的方法只使用Array.prototype.filter()
:
var tmp = {},
result = arr.filter(function (el) {
if (tmp.hasOwnProperty(el.id)) {
tmp[el.id].visit += el.visit;
return false;
}
else {
tmp[el.id] = el;
return true;
}
});
它也会重用对象,但这会使原始数组包含不准确的值。如果这是一个问题,您可以修改示例以将每个对象属性复制到新对象。