举例数组
const arr = [
{id: "1175310929766055936", pid: "", name: "总裁办" },'---返回空数组',
{id: "1175311213774962688", pid: "", name: "行政部" },'---返回空数组',
{id: "1175311267684352000", pid: "", name: "人事部" },'---返回空数组',
{id: "1175311325720936448", pid: "", name: "财务部" },
{id: "1175311373083017216", pid: "", name: "技术部" },
{id: "1175311418004013056", pid: "", name: "运营部" },
{id: "1175311466846683136", pid: "", name: "市场部" },
{id: "1235395178363559936", pid: "1175311325720936448", name: "财务核算部"},
{id: "1235398264104624128", pid: "1175311325720936448", name: "税务管理部"},
{id: "1235398536969265152", pid: "1175311325720936448", name: "薪资管理部"},
{id: "1235398608847052800", pid: "1175311373083017216", name: "Java研发部"},
{id: "1235398661355544576", pid: "1175311373083017216", name: "Python研发部"},
]
递归
第一次进入递归
数组内下标0的对象,的pid和设置的默认pid全等,符合if判断
进入if内执行代码
并触发递归
{id: "1175310929766055936", pid: "", name: "总裁办" } 的id被传参--作为pid arr数组也被传入
此时进入递归
再次判断--内部有循环, 将依次拿到数组内的每个对象的pid
和{id: "1175310929766055936", pid: "", name: "总裁办" }的id(递归函数内是pid)进行判断,
12个对象的pid 和{id: "1175310929766055936", pid: "", name: "总裁办" }都不全等,return空数组
此时递归函数被销毁
{id: "1175310929766055936", pid: "", name: "总裁办" }在外部函数被push到newArr内
然后进入第二次循环,forEach会执行12次(和双循环有异曲同工之妙,函数自己调用自己,进入递归,外部调用一次(此时外部循环走第一次)。递归函数内的循环会执行12次)(这不就是双循环么,外部走一次,内部走多次)
前三个对象进入了一层递归,但是返回了空数组,因为都不符合条件
每次递归函数每次创建使用完毕都会被销毁,再次递归里面的const newArr =[ ] 就被重新创建了,生成空数组(这里容易与外部const newArr =[]容易弄混,外部的const newArr =[]内是有被push内容的),递归调用自己的话,就是创建了一个和自己一模一样的函数,相当于一个新函数(长得一样而已)
跳过前三个---直接来到遍历下标3的对象
这里比前面复杂,递归内,再次进入递归,初始函数调用进入递归
递归内符合条件,再次进入里递归,进入二层递归
图中已经画出,进行非常详细的分析
初始函数
遍历得到下标3的对象 {id: "1175311325720936448", pid: "", name: "财务部" }
{id: "1175311325720936448", pid: "", name: "财务部" }的pid和初始的pid= ‘ ’ 全等进入if内
{id: "1175311325720936448", pid: "", name: "财务部" }的id被传入递归函数的形参pid里
arr就是原数组对象
再看递归--函数内
循环arr 拿到每一个对象并把每个对象的pid 和 {id: "1175311325720936448", pid: "", name: "财务部" }的id进行对比
此时第一个符合条件下标 7 的对象{id: "1235395178363559936", pid: "1175311325720936448", name: "财务核算部"}
会进入再次进入if判断
进入二层--递归
{id: "1235395178363559936", pid: "1175311325720936448", name: "财务核算部"}的id将会被再次传入 进入递归,直接说结果把,二层递归return会返回空数组
现在回到一层递归里
给{id: "1235395178363559936", pid: "1175311325720936448", name: "财务核算部"}加上children
并push到 const newArr =[]里(此处是递归里的 const newArr =[])。然后return
回到初始函数内
[ {id: "1235395178363559936", pid: "1175311325720936448", name: "财务核算部" ,children:[] } ]被return 到初始函数内 并被赋值给children
初始函数还停在这个对象 {id: "1175311325720936448", pid: "", name: "财务部" }=item
往下走
item.children = children
得到结果
{id: "1175311325720936448", pid: "", name: "财务部" ,children:[
{id: "1235395178363559936", pid: "1175311325720936448", name: "财务核算部"} ] }
并被push到 newArr
外部的 const newArr 所有的数据 push后的结果
const newArr =[
{id: "1175310929766055936", pid: "", name: "总裁办" },
{id: "1175311213774962688", pid: "", name: "行政部" },
{id: "1175311267684352000", pid: "", name: "人事部" },
{id: "1175311325720936448", pid: "", name: "财务部" ,children:[
{id: "1235395178363559936", pid: "1175311325720936448", name: "财务核算部"} ] }
]
后面就都是都是重复这些步骤
--------------------------------------------------------------------
代码还可以优化
上面写法也可以实现效果
但是所有对象都被加上children空数组,
在里面再加上一个判断
if(children.length > 0){
item.children=children
}
只有,有子级部门才会添加children数组
不加判断的效果
加上
if(children.length > 0){
item.children=children
}
后的效果
全部分析完毕
最终实现代码
const arr = [
{id: "1175310929766055936", pid: "", name: "总裁办" },
{id: "1175311213774962688", pid: "", name: "行政部" },
{id: "1175311267684352000", pid: "", name: "人事部" },
{id: "1175311325720936448", pid: "", name: "财务部" },
{id: "1175311373083017216", pid: "", name: "技术部" },
{id: "1175311418004013056", pid: "", name: "运营部" },
{id: "1175311466846683136", pid: "", name: "市场部" },
{id: "1235395178363559936", pid: "1175311325720936448", name: "财务核算部"},
{id: "1235398264104624128", pid: "1175311325720936448", name: "税务管理部"},
{id: "1235398536969265152", pid: "1175311325720936448", name: "薪资管理部"},
{id: "1235398608847052800", pid: "1175311373083017216", name: "Java研发部"},
{id: "1235398661355544576", pid: "1175311373083017216", name: "Python研发部"},
]
function treeArr(arr , pid=''){
const newArr =[]
arr.forEach(item => {
if(item.pid === pid){
const children = treeArr(arr , item.id)
if(children.length > 0){
item.children=children
}
newArr.push(item)
}
});
return newArr
}
console.log( treeArr(arr));