合并JavaScript Array中的重复项

时间:2014-04-29 07:12:33

标签: javascript arrays

我有一个愚蠢的问题,起初似乎很容易解决,但结果却很棘手。

我有一个对象数组,每个对象都有两个属性: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;!

谢谢!

3 个答案:

答案 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;
        }
    });

它也会重用对象,但这会使原始数组包含不准确的值。如果这是一个问题,您可以修改示例以将每个对象属性复制到新对象。