Ключом к успеху здесь является создание промежуточного формата, который позволяет легко искать.Поскольку вы работаете с массивами children
, вам в конечном итоге придется использовать filter
и find
всякий раз, когда вы добавляете что-то новое, для предотвращения дублирования и обеспечения группировки.
Работая с форматом, основанным на объектах иключи, намного проще выполнить группировку.
Мы можем создавать группы в одном вложенном цикле, что означает, что мы касаемся каждого элемента только один раз для основной логики.Группа имеет следующий формат:
{ "categoryName": { "subCategoryName": [ { id, name } ] } }
Затем, переход к требуемому формату { name, children }
- это вопрос еще одного цикла над записями этого дерева.В этом цикле мы переходим от { "categoryName": catData }
к { name: "categoryName", children: catData }
Вот пример, который показывает два шага отдельно:
const data=[{id:1,name:"Zend",category:"php",subCategory:["framework"]},{id:2,name:"Laravel",category:"php",subCategory:["framework"]},{id:3,name:"Vesion 5",category:"php",subCategory:["versions"]},{id:4,name:"Angular",category:"frontend",subCategory:["framework","typescript"]},{id:5,name:"Aurelia",category:"frontend",subCategory:["framework","typescript"]},{id:6,name:"JQuery",category:"frontend",subCategory:[]}];
// { category: { subCategory: [ items ] } }
const categoryOverview = data.reduce(
(acc, { id, name, category, subCategory }) => {
// Create a top level group if there isn't one yet
if (!acc[category]) acc[category] = {};
subCategory.forEach(sc => {
// Create an array for this subCat if there isn't one yet
acc[category][sc] = (acc[category][sc] || [])
// and add the current item to it
.concat({ id, name });
});
return acc;
},
{}
)
const nameChildrenMap = Object
.entries(categoryOverview)
// Create top level { name, children } objects
.map(([cat, subCats]) => ({
name: cat,
children: Object
.entries(subCats)
// Create sub level { name, children } objects
.map(([subCat, items]) => ({
name: subCat,
children: items
}))
}))
console.log(nameChildrenMap);