JS平铺对象数组转树结构

716 阅读2分钟

在工作中遇到了对象数组转成树结构的问题,在此记录一下,下次遇到方便回顾。 对于我这个小菜鸡来说,第一次遇到这种问题还是有点困难的,我搞了好久。。。没搞出来。记录自己问题的同时,也分享给和我遇到同样问题的小菜鸡。

  • 先看下效果,层级结构大致如图:(前提:原数据中需要存在父级的id)

image.png

看到这种树,其他博主也有很多方式来完成。也可以看下其他博主,参照一下递归的方式(其实我递归都理不清楚),但是用递归的话,数据量多了 ,会有性能问题的,当然哈最好的解决办法还是异步加载,这里分享的是同步加载树~,需要前端处理的情况,分享下我的项目组长(几年工作经验的大佬)写的方式~ 复杂度蹭蹭蹭降低。当然各位大佬看到了,有问题的话可以轻点指出来~

  • 对象数组转成数结构
// 原数组对象结构 这里的id key value 都是唯一标识哟
const flatList = const flatList = [
        {
            "id": "1-1",
            "title": "我是1-1",
            "pId": "1"
        },
        {
            "id": "1",
            "title": "我是1",
            "pId": "8"
        },
        {
            "id": "1-2",
            "title": "我是1-2",
            "pId": "1"
        },
        {
            "id": "2",
            "key": "2",
            "value": "2",
            "title": "我是2",
            "pId": ""
        },
        {
            "id": "1-1-1",
            "title": "我是1-1-1",
            "pId": "1-1"
        },
        {
            "id": "1-3",
            "title": "我是1-3",
            "pId": "1"
        },
        {
            "id": "3",
            "title": "我是3",
            "pId": ""
        },
        {
            "id": "3-1",
            "title": "我是3-1",
            "pId": "3"
        },
        {
            "id": "3-1-1",
            "title": "我是3-1-1",
            "pId": "3-1"
        },
        {
            "id": "3-1-1-1",
            "title": "我是3-1-1-1",
            "pId": "3-1-1"
        },
        {
            "id": "3-1-2",
            "title": "我是3-1-2",
            "pId": "3-1"
        }
    ];
// 目标对象结构
const targetList = [
    {
        "id": "1",
        "title": "我是1",
        "pId": "0",
        "children": [
            {
                "id": "1-1",
                "title": "我是1-1",
                "pId": "1",
                "children": [
                    {
                        "id": "1-1-1",
                        "title": "我是1-1-1",
                        "pId": "1-1",
                        "children": []
                    }
                ]
            },
            {
                "id": "1-2",
                "title": "我是1-2",
                "pId": "1",
                "children": []
            },
            {
                "id": "1-3",
                "title": "我是1-3",
                "pId": "1",
                "children": []
            }
        ]
    },
    {
        "id": "2",
        "key": "2",
        "value": "2",
        "title": "我是2",
        "pId": "",
        "children": []
    },
    {
        "id": "3",
        "title": "我是3",
        "pId": "",
        "children": [
            {
                "id": "3-1",
                "title": "我是3-1",
                "pId": "3",
                "children": [
                    {
                        "id": "3-1-1",
                        "title": "我是3-1-1",
                        "pId": "3-1",
                        "children": [
                            {
                                "id": "3-1-1-1",
                                "title": "我是3-1-1-1",
                                "pId": "3-1-1",
                                "children": []
                            }
                        ]
                    },
                    {
                        "id": "3-1-2",
                        "title": "我是3-1-2",
                        "pId": "3-1",
                        "children": []
                    }
                ]
            }
        ]
    }
]

话不多说:直接上代码

const setTree = (flatLists: TreeDataProps[]) => {
    const result = []; // 存放结果集
    const itemMap = {};   

    for (const item of flatList) { // 先转成map存储(id为键的)
        itemMap[item['id']] = {
            ...item,
            ['children']: [],
        };
    }
    for (const item of flatList) {
        const id = item['id'];
        const pid = item['pId'];
         // pid存在,但是id==pid的数据不存在的情况,name这个节点为一级节点    eg:id为1的,pId我写的8
        const pItem = pid ? itemMap[pid] : null;
        const treeItem = itemMap[id];

        if (!pItem) {
            result.push({ ...treeItem  });
        } else {
            itemMap[pid]['children'].push({ ...treeItem  });
        }
    } 
    return result;
};

总结下:主要是利用对象的引用+Map

通用的逻辑就是这样。你可以在这个基础上做一些其他业务逻辑