转载自等风来的博客:https://www.cnblogs.com/mengff/p/13142128.html
数组结构如下
const arr = [
{id:1, parentId: null, name: 'a'},
{id:2, parentId: null, name: 'b'},
{id:3, parentId: 1, name: 'c'},
{id:4, parentId: 2, name: 'd'},
{id:5, parentId: 1, name: 'e'},
{id:6, parentId: 3, name: 'f'},
{id:7, parentId: 4, name: 'g'},
{id:8, parentId: 7, name: 'h'},
]
方法1:利用map对象,空间换时间
function array2Tree(arr){
if(!Array.isArray(arr) || !arr.length) return;
let map = {};
arr.forEach(item => map[item.id] = item);
let roots = [];
arr.forEach(item => {
const parent = map[item.parentId];
if(parent){
(parent.children || (parent.children=[])).push(item);
}
else{
roots.push(item);
}
})
return roots;
}
方法2:利用递归
//需要插入父节点id,pid为null或'',就是找root节点,然后root节点再去找自己的子节点
function array2Tree(data, pid){
let res = [];
data.forEach(item => {
if(item.parentId === pid){
let itemChildren = array2Tree(data,item.id);
if(itemChildren.length) item.children = itemChildren;
res.push(item);
}
});
return res;
}
方法3:深度优先遍历
function dfs(root,fVisit){
let stack = Array.isArray(root) ? [...root] : [root];
while(stack.length){
let node = stack.pop();
fVisit && fVisit(node);
let children = node.children;
if(children && children.length){
for(let i=children.length-1;i>=0;i--) stack.push(children[i]);
}
}
}
方法4: 广度优先遍历
function dfs(root,fVisit){
let stack = Array.isArray(root) ? [...root] : [root];
while(stack.length){
let node = stack.pop();
fVisit && fVisit(node);
let children = node.children;
if(children && children.length){
for(let i=children.length-1;i>=0;i--) stack.push(children[i]);
}
}
}