1. ホーム
  2. javascript

[解決済み] オブジェクトの配列に対するgroupbyの最も効率的な方法

2022-03-23 07:48:34

質問

配列内のオブジェクトをグループ化する最も効率的な方法は何ですか?

例えば、このようなオブジェクトの配列があったとします。

[ 
    { Phase: "Phase 1", Step: "Step 1", Task: "Task 1", Value: "5" },
    { Phase: "Phase 1", Step: "Step 1", Task: "Task 2", Value: "10" },
    { Phase: "Phase 1", Step: "Step 2", Task: "Task 1", Value: "15" },
    { Phase: "Phase 1", Step: "Step 2", Task: "Task 2", Value: "20" },
    { Phase: "Phase 2", Step: "Step 1", Task: "Task 1", Value: "25" },
    { Phase: "Phase 2", Step: "Step 1", Task: "Task 2", Value: "30" },
    { Phase: "Phase 2", Step: "Step 2", Task: "Task 1", Value: "35" },
    { Phase: "Phase 2", Step: "Step 2", Task: "Task 2", Value: "40" }
]

この情報を表で表示しています。異なる方法でgroupbyしたいのですが、値の合計を出したいのです。

私はUnderscore.jsのgroupby機能を使っています。これは便利ですが、すべてのトリックを行うわけではありません。 group by メソッドを使用します。

私が求めているのは、(要求されれば)特定の値を合計することができることです。

つまり、もし私がgroupby Phase , 受け取りたいですね。

[
    { Phase: "Phase 1", Value: 50 },
    { Phase: "Phase 2", Value: 130 }
]

そして、グルーピーをした場合 Phase / Step , 受けてしまう。

[
    { Phase: "Phase 1", Step: "Step 1", Value: 15 },
    { Phase: "Phase 1", Step: "Step 2", Value: 35 },
    { Phase: "Phase 2", Step: "Step 1", Value: 55 },
    { Phase: "Phase 2", Step: "Step 2", Value: 75 }
]

あるいは、Underscore.jsを使用して、結果のオブジェクトをループして、自分で合計を行うことにこだわるべきでしょうか?

どのように解決するのですか?

外部ライブラリの使用を避けたい場合は、バニラバージョンの groupBy() というように。

var groupBy = function(xs, key) {
  return xs.reduce(function(rv, x) {
    (rv[x[key]] = rv[x[key]] || []).push(x);
    return rv;
  }, {});
};

console.log(groupBy(['one', 'two', 'three'], 'length'));

// => {3: ["one", "two"], 5: ["three"]}