javascript /下划线:按数组中的属性查找对象,并将它们组合在一起

时间:2014-09-05 18:09:16

标签: javascript arrays underscore.js

如果我有一个如下所示的对象数组:

[{id:1,product:'widget',quantity:10}, {id:2,product:'foobar',quantity:5}, {id:3,product:'widget',quantity:5}]

在javascript中是否有一种优雅的方式来查找具有相同名称的对象,并将数量合并到第一个对象中,并删除其余的对象?

结果数组如下所示:

[{id:1,product:'widget',quantity:15}, {id:2,product:'foobar',quantity:5}]

现在我正在创建一个新数组,迭代现有数组,查找具有特定名称的所有内容,执行总和,然后将其转储到新数组中。这一切似乎过于复杂。我用下划线来处理很多繁重的工作。

谢谢!

3 个答案:

答案 0 :(得分:3)

您可以groupBy产品,然后map生成的组,以获得所需的结构。 Reduce用于对数量求和:

    var groups = _.chain(data)
        .groupBy('product')
        .map( function(group){
            return {
                id: group[0].id,
                product: group[0].product,
                quantity: _.reduce(group, function(memo, value){ return memo + value.quantity; }, 0 )
            }
        })
        .value();

答案 1 :(得分:0)

尝试使用哈希表(Javascript中的Object):

var data = new Array(
    {id:1,product:'widget',quantity:10},
    {id:2,product:'foobar',quantity:5},
    {id:3,product:'widget',quantity:5}
);
var temp = new Object();
var newdata = new Array();

// Stuff your quantities into the hash table
for (var i=0; i<data.length; i++) {
    // If the product doesn't exist yet, create it and set the quantity to 0
    if (!temp.hasOwnProperty(data[i].product)) {
        temp[data[i].product] = 0;
    }
    // Increment the product quantity
    temp[data[i].product] += data[i].quantity;
}

// Split out the hash table into an array
for (product in temp) {
    newdata.push({"id":newdata.length+1, "product":product, "quantity":temp.product});
}

答案 2 :(得分:0)

你是否可以将结果不是正式数组而是传统对象?因为实际上,数组只是一种特殊类型的Object。通过这种方式,您可以像访问关联数组一样访问它,并且可以根据产品名称进行访问,这似乎是您关注的内容:

var results = {};
for(var i = 0; i < yourarr.length; ++i) {
  if(!results.hasOwnProperty(yourarr[i].product)) {
    results[yourarr[i].product] = {};
    results[yourarr[i].product].id = yourarr[i].id;
    results[yourarr[i].product].quantity = yourarr[i].quantity;
  }

  results[yourarr[i].product].quantity += yourarr[i].quantity;
}

//Can now access by doing say, console.log(results.widget);
//To loop through, you can do:
for(var key in results) {
  if(results.hadOwnProperty(key) { //Needed to ensure you don't access prototype elements
    console.log(results.key);
  }
}