数组转树形结构

500 阅读1分钟

本人平时做的业务也都是主要ToB端的稍微多一点,对于数组转树形结构用的场景其实并不算多,目前我想到的场景就是后端返回的菜单数组,前端把它转化成为树形结构,并渲染出来,下面上代码

    const response = [
        { id: 0, pid: null, name: 'a' },
        { id: 1, pid: 0, name: 'b' },
        { id: 2, pid: 0, name: 'c' },
        { id: 3, pid: 2, name: 'd' },
        { id: 4, pid: 2, name: 'e' },
        { id: 5, pid: null, name: 'f' },
        { id: 6, pid: 5, name: 'g' },
        { id: 7, pid: 5, name: 'h' },
        { id: 8, pid: 5, name: 'i' },
        { id: 9, pid: 6, name: 'i' },
        { id: 10, pid: 7, name: 'j' },
    ]
    
    function buildTree(list = []) {
        const idMap = list.reduce((prev, cur) => { // 先在这里转为对象结构,都是引用值
            prev[cur.id] = cur
            return prev
        }, {})
        // idMap的结构就变成了 { 0: 某某对象, 1: 某某对象 }等
        let resultTree = {} // 最后的结果
        list.forEach(item => { // 再遍历一遍,使id和pid相关引用地址链接起来
            const parent = idMap[item.pid] // 先找爹
            if (parent) { // 如果有爹,那么就把对象塞进来
                (parent.children || (parent.children = [])).push(item)
            } else { // 否则就是id终端,没有pid,考虑可能有多个根节点,用id作为最终对象的key存储
                resultTree[item.id] = item
            }
        })
        return JSON.parse(JSON.stringify(resultTree)) // 为了防止地址引用,直接克隆一份返回出去
    }
    
    
    console.log('buildTree(response)', buildTree(response))
    
    各位大佬如果有更好的意见或者方法,请多指教