利用递归的方法循环树形数组,当遇到有孩子的对象再次调用递归函数循环孩子数组,每次循环的数据放入一个提前声明好的数组里,等所有递归函数执行完,这个数组即是想要得到的扁平数据数组。
让res=[] const fn=(源)=祝辞{ source.forEach (el=祝辞{ res.push (el) 埃尔。孩子,,el.children.length> 0 & # 63;fn (el.children):“ }) } >之前
让res=[]//用于存储递归结果(扁平数据)//递归函数 const fn=(源)=祝辞{ source.forEach (el=祝辞{ res.push (el) 埃尔。孩子,,el.children.length> 0 & # 63;fn (el.children): "//子级递归 }) }//树形数据 const arr=( {id:“1”,排名:1}, {id:“2”,等级:1 孩子:( {id:“2.1”,排名:2}, {id:“2.2”,排名:2} ] }, {id:“3”,等级:1 孩子:( {id:“3.1”,排名:2 孩子:( {id:“3.1.1”,等级:3 孩子:( {id:“3.1.1.1”,排名:4 孩子:( {id:“3.1.1.1.1”,等级:5} ] } ] } ] } ] } ] fn (arr)//执行递归函数 console.log (res)//查看结果 >之前结果:
查看源码,
扁平数据转成树形数据,请参考这篇文章:js实现无限层级树形数据结构(创新算法)
<强>递归实现强>
函数transformTree(列表){ const树=[] (让我=0,len=list.length;我& lt;兰;我+ +){ 如果列表(![我].pid) { 常数项=queryChildren([我]列表,列表) tree.push(项) } } 回归树 } 函数queryChildren(父母,列表){ const孩子=[] (让我=0,len=list.length;我& lt;兰;我+ +){ 如果(列表[我]。pid===parent.id) { 常数项=queryChildren([我]列表,列表) children.push(项) } } 如果(children.length) { 的父母。=孩子 } 回报父母 } >之前尽管后续对上面的算法进行了很多优化,但是仍未离开递归,递归可能遇到的问题还是会有可能遇到
<强>循环实现强>
随着进化,循环代替递归是必然的结果~
<强>两次循环强>
开始使用循环实现时,使用了两次循环完成转换,先进行一次循环将数据转换地图成结构,使其能通过id快速查询
函数transformTree(列表){ const树=[] const记录={} const长度=list.length (让我=0;我& lt;长度;我+ +){ 常数项=列表(我) 项。孩子=[]//重置孩子 记录项目。id]=项目 } (让我=0;我& lt;长度;我+ +){ 常数项=列表(我) 如果(item.pid) { 如果(记录(item.pid)) { 记录[item.pid] .children.push(项) } 其他}{ tree.push(项) } } 回归树 } >之前上面的算法相较于递归的实现,不存在栈溢出的问题,而且是线性复杂度,效率已经提高了许多
<强>一次循环强>
再进行一定的优化,最后变成一次循环完成树形构建
函数transformTree(列表){ const树=[] const记录={} (让我=0,len=list.length;我& lt;兰;我+ +){ 常数项=列表(我) const id=item.id 如果(记录(id)) { 项。孩子=记录(id) 其他}{ 项。孩子=记录[id]=[] } 如果(item.pid) { 如果(!记录[item.pid]) { 记录项目。pid]=[] } 记录[item.pid] .push(项) 其他}{ tree.push(项) } } } >之前使用对象变量的特性,使用地图结构直接指向儿童数组,在循环中初始化的同时还能快速查找插入相应的孩子里,使其在一次循环内完成构建,最后附上完整版~
函数transformTree(列表,选择={}){ const { keyField=癷d”, childField='孩子', parentField=浮? }=选项 const树=[] const记录={} (让我=0,len=list.length;我& lt;兰;我+ +){ 常数项=列表(我) const id=项目(keyField) 如果(id) { 继续 } 如果(记录(id)) { 项[childField]=记录(id) 其他}{ 项[childField]=[id]=[]记录 } 如果(项目(parentField)) { const parentId=项目(parentField) 如果(!记录[parentId]) { 记录[parentId]=[] } 记录[parentId] .push(项) 其他}{ tree.push(项) } } 回归树 }js实现树形数据转成扁平数据的方法示例