JS-Tree中递归找多个子集,且对子集有其他操作

353 阅读2分钟

业务场景:

可以拿到tree结构,也可以拿到选择的一个或多个子集的id数组。需要找到该子集下的所有子集并给所有子集增加一个属性。

数据结构

const selectedArr = ['1-1', '3-1'];
const tree = [
    {
        "id": "1",
        "title": "我是1",
        "pId": "8",
        "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 getTreeNode = (tree: any, id: any) => { // 找到当前选中得节点及所有子节点
    for (let index = 0; index < tree.length; index++) {
        const element = tree[index];
        if (element.id === id) {
            return element;
        } else {
            const result: any = getTreeNode(element.children, id);
            if (result) {
                return result;
            }
        }
    }
};


// 遍历找到的节点及所有子节点,并添加或修改某个属性设置
const forEachTree = (tree: any[], callback: any) => { 
    for (let index = 0; index < tree.length; index++) {
        const element = tree[index];
        callback(element);
        if (element.children && element.children.length > 0) {
            forEachTree(element.children, callback);
        }
    }
};

// 这两个操作分开更好理解但是两次递归可能不太好~~~
const allAllowFleetNode = allowFleetIds.map(item => getTreeNode(tree, item)).filter(i => i);
forEachTree(allAllowFleetNode, (item: any) => {
    item && (item.disableCheckbox = true);
});

tree结果


const tree = [
    {
        "id": "1",
        "title": "我是1",
        "pId": "8",
        "children": [
            {
                "id": "1-1",
                "title": "我是1-1",
                "pId": "1",
                "children": [
                    {
                        "id": "1-1-1",
                        "title": "我是1-1-1",
                        "pId": "1-1",
                        "children": [],
                        "disableCheckbox": true
                    }
                ],
                "disableCheckbox": true
            },
            {
                "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": [],
                                "disableCheckbox": true
                            }
                        ],
                        "disableCheckbox": true
                    },
                    {
                        "id": "3-1-2",
                        "title": "我是3-1-2",
                        "pId": "3-1",
                        "children": [],
                        "disableCheckbox": true
                    }
                ],
                "disableCheckbox": true
            }
        ]
    }
]

总结

运用递归和对象的引用直接修改的tree。

优化

可以参考我发的 对象数组转树结构这篇文章,思路类似,直接遍历平铺的数据,但是要拿到selectedArr下所有的自己的id(这里就可以用下getTreeNode,然后树状的结构又递归一下平铺数据,额好像又跟这里差不多了,但是数据量要小点点)然后转成id为键的Map对象。遍历时 找到id一样的 直接修改或增加属性即可。