JavaScript オブジェクト配列をsqlのgroup byのように集計する
JavaScript
のオブジェクト配列(json
も同様)をSQL
のGROUP BY
のように集計します。
具体的には以下のようなことができるようになります。
var arr = [
{
name: 'バナナ',
category: 'フルーツ',
price: 100
},
{
name: 'りんご',
category: 'フルーツ',
price: 120
},
{
name: 'みかん',
category: 'フルーツ',
price: 30
},
{
name: 'トマト',
category: '野菜',
price: 200
},
{
name: 'キャベツ',
category: '野菜',
price: 150
}
];
// 集計後
// カテゴリーごとの個数(要素数)と金額を集計
[
{
category: 'フルーツ',
count: 3,
price: 150
},
{
category: '野菜',
count: 2,
price: 350
},
];
実装方法
いろいろとやり方はあるかと思いますが、今回はreduce
関数を使用します。
reduce
関数の使い方についてはJavaScript reduce関数の基本的な使い方で紹介しています。
var group = arr.reduce(function (result, current) {
var element = result.find(function (p) {
return p.category === current.category
});
if (element) {
element.count ++; // count
element.price += current.price; // sum
} else {
result.push({
category: current.category,
count: 1,
price: current.price
});
}
return result;
}, []);
console.log(group);
/* 出力結果
[
{
category: 'フルーツ',
count: 3,
total: 150
},
{
category: '野菜',
count: 2,
price: 350
},
]
*/
reduce
関数は慣れていないとわかりづらいかもしれませんが、使いこなせればとても簡単に配列やオブジェクトを集計できるようになります。
ES2015の表記
アローファンクションやconst
を使用するとさらにシンプルになります。
const group = arr.reduce((result, current) => {
const element = result.find((p) => p.category === current.category);
if (element) {
element.count ++; // count
element.price += current.price; // sum
} else {
result.push({
category: current.category,
count: 1,
price: current.price
});
}
return result;
}, []);
IE8以下の対応
IE8
以下はreduce
関数が使用できません。
下記のURLで紹介されているfunction
を実装すればreduce
関数を使用できるようになります。