プロパティによってオブジェクトをグループ化したいです
オブジェクトの配列を、プロパティによってグループ化したいです。
想定するデータは以下のような感じです。
const data = [
{ type: '野菜', color: '赤', name: 'トマト' },
{ type: '野菜', color: '赤', name: 'パプリカ' },
{ type: '野菜', color: '緑', name: 'ブロッコリー' },
{ type: '果物', color: '紫', name: 'ぶどう' },
];
最終的に望む形式は以下のような感じです。
const groupingData = {
'野菜': {
'赤': ['トマト', 'パプリカ'],
'緑': ['ブロッコリー'],
},
'果物': {
'紫': ['ぶどう'],
},
};
MDNにやりたいことが載ってた
まさにずばりやりたいことがそのまま載ってました。
Array.prototype.reduce()
を使います。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#Grouping_objects_by_a_property
// MDNに載っていたコードそのまま抜粋
return objectArray.reduce(function (acc, obj) {
let key = obj[property]
if (!acc[key]) {
acc[key] = []
}
acc[key].push(obj)
return acc
}, {});
今回の形式バージョンを考えました
// MDNに載っていたコードを少し改造
const groupBy = (objectArray, property, optionProperty = '') => {
return objectArray.reduce((acc, obj) => {
const key = obj[property];
if (!acc[key]) {
acc[key] = [];
}
if (optionProperty && obj.hasOwnProperty(optionProperty)) {
acc[key].push(obj[optionProperty]);
} else {
acc[key].push(obj);
}
return acc;
}, {});
};
// 階層構造にする
const createGroupingData = (objectArray, property1, property2, property3) => {
const groupingData = groupBy(objectArray, property1);
Object.keys(groupingData).forEach((key) => {
groupingData[key] = groupBy(groupingData[key], property2, property3);
});
return groupingData;
};
// 使い方
const groupingData = createGroupingData(data, 'type', 'color', 'name');
もっと良い方法を教えて下さい。
再帰的な感じにしたいです。