2

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"}
     ]

型のリストを取得し、それらの型のコレクションを検索し、値を合計し、合計で新しい配列を作成することを伴わない、これを行うエレガントな方法はありますか?

4

3 に答える 3

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];
于 2013-11-13T05:45:26.003 に答える
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)
于 2013-11-13T06:12:41.847 に答える