js数组转换拼接成树结构

前端数组转为树结构在我们平时开发中经常遇到,主要用到了递归回调。下面的做法可提供一种转换思路。

我们拿到的数据格式是

let list= [
        { id: '1', parentId: '', name: '1' },
        { id: '2', parentId: '', name: '2' },
        { id: '3', parentId: '1', name: '3' },
        { id: '4', parentId: '3', name: '4' },
        { id: '5', parentId: '2', name: '5' },
        { id: '6', parentId: '5', name: '6' },
        { id: '7', parentId: '6', name: '7' },
    ]

我们想要用来渲染页面的格式是

newList = [
    {
        name: '1',
        id: '1',
        parentId: '',
        child: [
            {
                id: '3', 
                parentId: '1',
                name: '3',
                child: [
                    { 
                        id: '4', 
                        parentId: '3', 
                        name: '4',
                        child: []
                 }
                ]
            }
        ]
    },
    { 
        id: '2',
        parentId: '', 
        name: '2',
        child: [
            { 
                id: '5',
                parentId: '2', 
                name: '5',
                child: [
                    { 
                        id: '6',
                        parentId: '5',
                        name: '6',
                        child: [
                            { 
                                id: '7', 
                                parentId: '6', 
                                name: '7',
                                child: []
                            },
                      ]
                     },
                ],
            },
        ]
    }
]

第一步,找出最上面的节点。很明显的parentId为空的数据是最上面的节点。

// 首先对数据深拷贝一份数据,因为下面的处理会影响原数组
        let curList = JSON.parse(JSON.stringify(list))
        let newList = []
        for(let i = 0; i < curList.length; i++) {
            if(!curList[i].parentId) {
                curList[i].child = []
                newList.push(curList[i])
                curList.splice(i, 1)  // 筛选后做删除
                i--
            }
        }

第二步,找出第二节点加到父节点child数组里面

       travChild(curList, newList)
        function travChild(curList, newList) {
            for(let i = 0; i < curList.length; i++) {
                for(let j = 0; j < newList.length; j++) {
                    if (curList[i].parentId === newList[j].id) {
                        curList[i].child = []
                        newList[j].child.push(curList[i])
                        curList.splice(i, 1)
                    }
                }
            }
            // 第三步,找出第三节点,加到第二节点
            let twinNode = treeEndNode(newList)  // 获取第二节点
            if (curList.length) {
                travChild(curList, twinNode)
            }
            // 第n步,回调第三的步骤
        }

        function treeEndNode(tree, twinList = []) {
            tree.map(item => {
                if (item.child.length) {
                    treeEndNode(item.child, twinList)
                } else {
                    twinList.push(item)
                }
            })
            return twinList
        }

newList 就是我们的结果。
步骤二三也可以这样处理,可以防止curList.length的值不为空的时候无限循环回调

function travChild(curList, newList) {
            for(let i = 0; i < curList.length; i++) {
                for(let j = 0; j < newList.length; j++) {
                    if (curList[i].parentId === newList[j].id) {
                        curList[i].child = []
                        newList[j].child.push(curList[i])
                        curList.splice(i, 1)
                    }
                }
            }
            // 第n层
            newList.map(item => {
                if (item.child.length) {
                    travChild(curList,item.child)
                }
            })
        }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容