Javascript:汇总集合中的对象

时间:2013-11-13 05:28:04

标签: javascript

我正在寻找一种在javascript中整合对象集合的方法。 例如,我有一个集合:

inventory = [ 
    {count: 1, type: "Apple"},
    {count: 2, type: "Orange"},
    {count: 1, type: "Berry"},
    {count: 2, type: "Orange"},
    {count: 3, type: "Berry"}
]

我最终想要的是:

   inventory = [
        {count: 1, type: "Apple"},
        {count: 4, type: "Orange"},
        {count: 4, type: "Berry"}
     ]

有没有一种优雅的方法可以做到这一点,不涉及获取类型列表,在我的集合中搜索这些类型,对值进行求和,以及使用总和创建一个新数组?

3 个答案:

答案 0 :(得分:3)

它不是太漂亮,但这样做会。它创建项目类型/计数的字典,以及最终总和的列表。 inventoryDict用于轻松查找现有计数,而summedInventory包含总计项目的最终列表。

var inventory = [ /* ... */ ];
var summedInventory = [];
var inventoryDict = {};

for (var i = 0; i < inventory.length; i++) {
    var item = inventory[i];
    if (!(item.type in inventoryDict)) {
        inventoryDict[item.type] = {type: item.type, count: 0};
        summedInventory.push(inventoryDict[item.type]);
    }
    inventoryDict[item.type].count += item.count;
}

这是假设你不想改变库存物品 - 如果你不介意改变物品,可以稍微简化一下。

要避免中间变量并以更实用的方式执行,可以使用Array.reduce:

var newInventory = inventory.reduce(function(acc, item) {
    var summedInventory = acc[0], inventoryDict = acc[1];

    if (!(item.type in inventoryDict)) {
        inventoryDict[item.type] = {type: item.type, count: 0};
        summedInventory.push(inventoryDict[item.type]);
    }

    inventoryDict[item.type].count += item.count;
    return acc;
}, [[], {}])[0];

答案 1 :(得分:1)

我的解决方案是:

inventory = [ 
    {count: 1, type: "Apple"},
    {count: 2, type: "Orange"},
    {count: 1, type: "Berry"},
    {count: 2, type: "Orange"},
    {count: 3, type: "Berry"}
];

result = {};
inventory.map(function(item) {
    console.log(item);
    var count = result[item.type] || 0;
    result[item.type] = item.count + count;
});

inventory = [];

for (property in result) {
    inventory.push({count: result[property], type: property});
}

console.log(inventory);

请参阅this jsfiddle

答案 2 :(得分:1)

使用Javascript的Array.reduce

这是一种相对简单的方式
var reduced = inventory
    .reduce(function(sum,current) {
        var found = false
        sum.forEach(function(row,i) {
            if (row.type === current.type) {
                sum[i].count += current.count
                found = true;
            }
        })
        if (found === false) sum.push(current)
        return sum
    }, [])

console.log(reduced)