- 这里换一种思路实现数组转成树图
思路:自己维护一个队列。 通过arr.shift() 和 arr.push() 实现队列的先进先出: FIFO
1.1 先从队列中弹出一个孩子,尝试把它插入树中去;
1.2 如果插入成功,则继续弹出下一个孩子。
1.3 如果插入不成功,则把这个孩子放到队尾。
1.4 基线条件:当队列中没有孩子时,说明树图插入完成。
const familyArray = [
{ id: "09", name: "贾元春", pId: "03" },
{ id: "10", name: "贾探春", pId: "03" },
{ id: "11", name: "林黛玉", pId: "04" },
{ id: "12", name: "巧姐", pId: "05" },
{ id: "13", name: "贾兰", pId: "07" },
{ id: "01", name: "贾母", pId: "-1" },
{ id: "02", name: "贾赦", pId: "01" },
{ id: "03", name: "贾政", pId: "01" },
{ id: "04", name: "贾敏", pId: "01" },
{ id: "05", name: "贾琏", pId: "02" },
{ id: "06", name: "贾迎春", pId: "02" },
{ id: "07", name: "贾珠", pId: "03" },
{ id: "08", name: "贾宝玉", pId: "03" },
];
// 插入函数
const insert = (tree, item) => {
const { pId } = item;
if (pId === "-1") {
tree.push(item);
return true;
} else {
const parentNode = findNodeById(tree, pId);
if (parentNode) {
console.log("父节点存在");
if (!parentNode.children) { parentNode.children = [] }
parentNode.children.push(item);
return true;
} else {
console.log("父节点不存在");
return false;
}
}
};
// 查找通过id查找节点
const findNodeById = (tree, id) => {
let node=null;
if(tree.length<1){return node}
for(let i=0;i<tree.length;i+=1){
const item=tree[i];
if (item.id === id) {
node=item;
return node
} else if ( item.children) {
node=findNodeById(item.children, id);
if(node){ return node}
}
}
return node
};
const ArrayToTree=(familyArray)=>{
// 分而治之
// 1. 创建根节点
const tree = [];
// 自行维护 [] 从队尾压入:push 从队头弹出shift
const queue = [...familyArray];
while(queue.length>0){
// 先弹出第一个
const firstItem=queue.shift();
if(insert(tree,firstItem)){
console.log(`插入成功${firstItem.name}`)
}else{
queue.push(firstItem);
console.log(`插入失败${firstItem.name}`);
}
}
return tree;
};
const familyArrayCopy=JSON.parse(JSON.stringify(familyArray));
const newFamilyTree=ArrayToTree(familyArrayCopy);
console.log("familyTree",familyArray);
console.log("newFamilyTree",newFamilyTree);