問題
あなたは次のような構造を持つ配列を操作することになりました。
const categories = [
{
categoryName: 'Fruits',
isDisplay: true,
subCategories: [
{
subCategoryName: 'Apples',
isDisplay: true
},
{
subCategoryName: 'Bananas',
isDisplay: false
}
]
},
{
categoryName: 'Vegetables',
isDisplay: false,
subCategories: [
{
subCategoryName: 'Carrots',
isDisplay: false
}
]
},
{
categoryName: 'Dairy',
isDisplay: true,
subCategories: []
}
];
この配列から、isDisplay: true のカテゴリとそのサブカテゴリだけを抽出した新しい配列を作成する関数を作成してください。
ただし、カテゴリが isDisplay: false の場合、そのサブカテゴリも非表示とみなします。
ルール
- 配列やオブジェクトの元の構造は維持すること。
- 元の配列やオブジェクトは変更しないこと。
期待する出力結果
[
{
categoryName: 'Fruits',
isDisplay: true,
subCategories: [
{
subCategoryName: 'Apples',
isDisplay: true
}
]
},
{
categoryName: 'Dairy',
isDisplay: true,
subCategories: []
}
]
回答例
function filterCategories(categories) {
return categories
.filter(category => category.isDisplay)
.map(category => {
return {
...category,
subCategories: category.subCategories.filter(subCategory => subCategory.isDisplay)
};
});
}
console.log(filterCategories(categories));
処理の解説
基本的にfilterとmapを利用して問題解決を行なっています。
1.最初の filter() メソッドは配列 categories から isDisplay プロパティが true のカテゴリを抽出します。これにより、非表示のカテゴリは新しい配列から除外されます。
categories.filter(category => category.isDisplay)
2.次に map() メソッドを用いて、上記のフィルタリングされたカテゴリそれぞれについて次の処理を行います。
.map(category => {
return {
...category,
subCategories: category.subCategories.filter(subCategory => subCategory.isDisplay)
};
})
この .map() メソッドのコールバック関数内では、スプレッド構文(...)と filter() メソッドを使って新しいオブジェクトを作成しています。
スプレッド構文を利用してオブジェクトを生成しているので、元のオブジェクトには影響を与えません。