树与数组的转换

数组转树

我们可以先对数组进行一个遍历,并且在遍历的过程中找出根节点,并且通过pid将有着父子关系的节点进行映射。后续为树的节点添加子节点会更快速。

function arrToTree(arr,rootId){
            if(!Array.isArray(arr)) throw new Error('arr is not an Array')
            let root = null
            const pMap = new Map()
            // 完成pid映射
            arr.forEach(item=>{
                const { id , name , pid} = item
                if(pMap.has(pid)){
                    const children =  pMap.get(pid)
                    children.push({id,name})
                    pMap.set(pid,children)
                }else{
                    pMap.set(pid,[{id,name}])
                }
                if(id==rootId){
                    root = {
                        id,
                        name,
                        children:[]
                    }
                }
            })
            appedChildren(root,pMap.get(root.id))
            function appedChildren(curNode,children){
                if(!Array.isArray(children)) return
                if(!curNode.children) curNode.children = []
                children.forEach(child=>{
                    if(pMap.has(child.id)){
                        // 有孩子
                        appedChildren(child,pMap.get(child.id))
                    }
                    curNode.children.push(child)
                })
            }
            return root
        }

树转数组(广度优先)

广度优先遍历由于是按照层级来的,所以我们可以采用队列的方式,当节点出队列的时候,把它的子节点进行入队,此时就可以保证顺序。

 function treeToArr(root){
            const queue = []
            queue.unshift(root)
            const list = []
            while(queue.length){
                const curNode = queue.pop()
                list.push({id:curNode.id,name:curNode.name})
                const children = curNode.children
                if(children&&children.length){
                    children.forEach(child=>{
                        queue.unshift(child)
                    })
                }
            }
            return list
        }

找所有父级(树形)

因为如果到达叶子节点还不是目标id,则说明不在这个树上,则needChild是null,同理其不在目标节点数上的那条线needChild都是null

function findNodeParentTree(root,nodeId){
            let rstRoot = null
            const curNode = root
            if(curNode.id == nodeId){
                curNode.children ? delete curNode.children : ''
                rstRoot = curNode
            }else{
                const children = curNode.children
                if(children&&children.length){
                    let needChild = null
                    children.some(child=>{
                        needChild = findNodeParent(child,nodeId)
                        //因为如果到达叶子节点还不是目标id,则说明不在这个树上,则needChild是null,同理其不在目标节点数上的那条线needChild都是null
                        if(needChild) return true
                    })
                    if(needChild){
                        rstRoot = {
                            id:curNode.id,
                            name:curNode.name,
                            children: [ needChild ]
                        }
                    }
                }
            }
            return rstRoot
        }

找所有父级(数组)

和上一个思想一样,只是此处是利用数组收集,则可以使用concat进行数组合并。

 function getParents(list,id){
            for(let i in list){
                if(list[i].id === id){
                    return [{ id:list[i].id , name:list[i].name }]
                }
                if(list[i].children && list[i].children.length > 0){
                    let result = getParents(list[i].children,id);
                    if(result){
                        return result.concat({ id:list[i].id , name:list[i].name })
                    }
                }
            }
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值