以下のように配列が与えられている時に、重複しているものをカテゴリ分けして、それぞれに紐づくプロパティの値を子要素として出力させる結果を得たいと思った。(画像①のようなイメージ)
constant.js
const fruits = [{
name: 'apple',
price: 100
},
{
name: 'apple',
price: 500
},
{
name: 'apple',
price: 1000
},
{
name: 'banana',
price: 100
},
{
name: 'banana',
price: 300
},
{
name: 'banana',
price: 500
},
{
name: 'banana',
price: 700
},
{
name: 'orange',
price: 100
},
{
name: 'orange',
price: 300
},
];
アプローチとしては以下。
1.配列のプロパティの値が全部で何種類なのか検出する
2.それぞれのpriceを配列として更にグループ分け
3.二重のfor文で表示させる
以下のようなコードを買いたところ、期待通りの結果を得ることが出来た。
index.js
function fruitArrGroupBy(list, keyGetter) {
const map = new Map();
list.forEach((item) => {
const key = keyGetter(item);
const collection = map.get(key);
if (!collection) {
map.set(key, [item]);
} else {
collection.push(item);
}
});
return map;
}
var groupedFruitArr = fruitArrGroupBy(fruits, fruit => fruit.name);
//配列のキーが何種類あるのかを出す(重複を外した配列を生成する)
var fruitTypeList = fruits.filter(function(v1,i1,a1){
return (a1.findIndex(function(v2){
return (v1.name===v2.name)
}) === i1);
});
//HTMLにレンダリング
for (let i = 0; i < fruitTypeList.length; i++) {
$("body").append(`<h1>${fruitTypeList[i].name}</h1>
<ul class="wrapper${i}"></ul>`);
$("body").append(``);
var fruitItemArray = groupedFruitArr.get(`${fruitTypeList[i].name}`);
for(var j = 0;j < fruitItemArray.length ;j++){
$(`.wrapper${i}`).append(`<li>${fruitItemArray[j].price}円</li>`)
}
}
しかし、もっとコードを改良出来るのではと思い信頼のおける先輩に相談したところ、親切に色々とフィードバックいただき、ここまで短くすることができた。
(※大きな表示の変更は変わらないという前提で)
index.js
var fruitsObj = {};
var fruitsObjArr = [];
// fruitsObj[number] = { name: 'Newcomer!' },
for (var k = 0; k < fruits.length; k++) {
//キー名に配列の値が無かったら
if (fruits[k].name in fruitsObj != true) fruitsObjArr = [];
fruitsObjArr.push(fruits[k].price);
console.log(fruitsObjArr);
fruitsObj[fruits[k].name] = fruitsObjArr;
}
console.log(fruitsObj);
for (const key in fruitsObj) {
$('body').append(`<h1>${key}</h1><ul class="wrapper-${key}"></ul>`);
if (fruitsObj.hasOwnProperty(key)) {
for (let i = 0; i < fruitsObj[key].length; i++) {
$(`.wrapper-${key}`).append(`<li>${fruitsObj[key][i]}円</li>`)
}
}
}