假设我有一个这样的数组
const ar = [
{id: 1, name: "A", parent: null},
{id: 2, name: "B", parent: 1},
{id: 11, name: "AA", parent: 1},
{id: 12, name: "AB", parent: 1},
{id: 111, name: "AAA", parent: 11},
{id: 41, name: "CC", parent: 4},
{id: 4, name: "C", parent: 1},
];
如何创建一个像这样只有一个对象的层次结构
{
id: 1,
name: "A",
parent: null,
children: [
{
id: 11,
name: "AA",
parent: 1,
children: [
{id: 111, name: "AAA", parent: 11}],
},
{id: 2, name: "B", parent: 1, children: []},
{
id: 4,
name: "C",
parent: 1,
children: [{id: 41, name: "CC", parent: 4, children: []}],
},
],
}
id
实际上不是一个数字在我的实际应用程序。它是一个随机字符串BTW。
我可以通过钻取children
数组递归地完成它,但这不是最有效的方法。有人能帮帮忙吗?
const ar = [
{id: 1, name: "A", parent: null},
{id: 2, name: "B", parent: 1},
{id: 11, name: "AA", parent: 1},
{id: 12, name: "AB", parent: 1},
{id: 111, name: "AAA", parent: 11},
{id: 41, name: "CC", parent: 4},
{id: 4, name: "C", parent: 1},
];
const hierarchy = (arr) => {
const map = {};
let root;
for (const ele of arr) {
map[ele.id] = ele;
ele.children = [];
}
for (const ele of arr) {
if (map[ele.parent] != undefined)
map[ele.parent].children.push(ele);
else
root = ele;
}
return root;
}
console.log(hierarchy(ar));
第一步是通过id映射项目,这样您就可以轻松查找,这样您就不会多次循环遍历数组。之后,您只需要循环并将子数组添加到父数组并添加引用。
const ar = [
{id: 1, name: "A", parent: null},
{id: 2, name: "B", parent: 1},
{id: 11, name: "AA", parent: 1},
{id: 12, name: "AB", parent: 1},
{id: 111, name: "AAA", parent: 11},
{id: 41, name: "CC", parent: 4},
{id: 4, name: "C", parent: 1},
];
// make a look up by the id
const mapped = ar.reduce((acc, item) => {
acc[item.id] = item;
return acc;
}, {});
// loop over
const result = ar.reduce((acc, item) => {
// if there there is no parent, we know it is the first so return it
const parentId = item.parent;
if (!parentId) return item;
// if we have a parent, see if we found this yet, if not add the array
mapped[parentId].children = mapped[parentId].children || [];
// set the item as a child
mapped[parentId].children.push(item);
return acc;
}, null);
console.log(result)
可以遍历数组,每次都将元素压入正确的位置。
要获得根,您可以检索没有父元素的元素。
const arr = [{id: 1, name: "A", parent: null},
{id: 2, name: "B", parent: 1},
{id: 11, name: "AA", parent: 1},
{id: 12, name: "AB", parent: 1},
{id: 111, name: "AAA", parent: 11},
{id: 41, name: "CC", parent: 4},
{id: 4, name: "C", parent: 1}]
arr.forEach(elem => elem.children = [])
arr.forEach(elem => {
if(elem.parent){
const parent = arr.find(x => x.id === elem.parent)
if(parent)parent.children.push(elem)
}
})
console.log(arr.find(x => !x.parent))
注意:如果你想再优化一点,你可以在第二个forEach