JS 实现树形结构的各种操作(2)

一 数据源

        以下所有操作,都使用本数据做测试。

const oraData = [
    {
        id: "1",
        name: "动物",
        children: [
            {
                id: "1-1",
                name: "哺乳类",
                children: [
                    {
                        id: "1-1-1",
                        name: "小猫",
                        children: []
                    },
                    {
                        id: "1-1-2",
                        name: "小狗",
                        children: []
                    },
                    {
                        id: "1-1-3",
                        name: "小猪",
                        children: []
                    }
                ]
            },
            {
                id: "1-2",
                name: "鸟类",
                children: [
                    {
                        id: "1-2-1",
                        name: "燕子",
                        children: []
                    },
                    {
                        id: "1-2-2",
                        name: "喜鹊",
                        children: []
                    },
                    {
                        id: "1-2-3",
                        name: "鹦鹉",
                        children: []
                    }
                ]
            }
        ]
    },
    {
        id: "2",
        name: "水果",
        children: [
            {
                id: "2-1",
                name: "苹果",
                children: []
            },
            {
                id: "2-2",
                name: "香蕉",
                children: []
            }
        ]
    },
    {
        id: "3",
        name: "蔬菜",
        children: []
    }
];

二  遍历tree,生成序号(像文章的一级标题、二级标题)

先看结果:每个name后面的文字都生成了序号,二级标题前面也有一级标题序号。

实现源码

const createSerialNumber = (tree, parentNo = '') => {
    const result = [];
    tree.forEach((node, index) => {
        // 如果当前没有父序号,则当前序号不加点。
        let currentNo = `${index + 1}`;
        // 如果有父序号,则父序号后面加点。
        if (parentNo) {
            currentNo = `${parentNo}.${index + 1}`;
        }
        // 创建新对象
        const newNode = {
            id: node.id,
            name: `${currentNo} ${node.name}`,
        };

        // 将新节点添加到结果数组中
        result.push(newNode);

        // 如果节点有子节点,递归遍历子节点
        if (node.children && node.children.length > 0) {
            const childResult = createSerialNumber(node.children, currentNo);
            result.push(...childResult); // 将子节点的结果合并到主结果中
        }
    });
    return result;
};

console.log(createSerialNumber(oraData));

三   删除tree 节点,如果是父节点,同时需要删除子节点。

 先看结果,删除了第一个节点(id=“1”)。

实现源码

const deleteTreeNodes = (data, deleteNode) => {
    var newTree = data.filter((item) => item.id !== deleteNode)
    newTree.forEach((item) => item.children && (item.children = deleteTreeNodes(item.children, deleteNode)))
    return newTree
}

console.log(JSON.stringify(deleteTreeNodes(oraData, "1"), null, 2));

四  更新节点内容

先看结果,替换了节点id为“2-2”的内容。

                 

实现源码:

const updateTreeNode = (tree, keyToUpdate, newValue) => {
    // 遍历树的每个节点
    for (let i = 0; i < tree.length; i++) {
        const node = tree[i];
        // 检查是否找到匹配的节点
        if (node.id === keyToUpdate) {
            // 更新节点的 designItem
            node.name = newValue;
            // 如果不需要继续搜索,可以直接返回
            return tree;
        }
        // 如果节点有子节点,递归调用函数
        if (node.children && node.children.length > 0) {
            updateTreeNode(node.children, keyToUpdate, newValue);
        }
    }
    // 如果没有找到匹配的节点,返回原树
    return tree;
}

console.log(JSON.stringify(updateTreeNode(oraData, "2-2", "火龙果"), null, 2));

五  新增选择节点的同级节点

先看结果,在节点id为“3”后面新增了一个id为“4”的交通工具的节点。

实现代码:

const addSameLevelNode = (tree, newNode, targetKey) => {
    // 递归遍历树结构
    const traverse = (nodes) => {
        for (let i = 0; i < nodes.length; i++) {
            const node = nodes[i];
            // 检查当前节点是否是要添加同级节点的目标节点
            if (node.id === targetKey) {
                // 在目标节点之后添加新节点
                nodes.splice(i + 1, 0, newNode);
                // 添加完成,停止遍历
                return;
            }
            // 如果有子节点,则递归遍历子节点
            if (node.children && node.children.length > 0) {
                traverse(node.children);
            }
        }
    }

    // 开始遍历树的根节点
    traverse(tree);
}

const getNewTreeData = () => {
    const treeData = JSON.parse(JSON.stringify(oraData));
    const newNode = {id: "4", name: "交通工具", children: []}
    addSameLevelNode(treeData, newNode, "3");
    return treeData;
};

console.log(JSON.stringify(getNewTreeData(), null, 2));

六  新增选择节点的子节点 

先看结果,在【蔬菜】节点里面添加一个【番茄】的子节点。

                 

实现源码:

const addChildNode = (tree, parentId, newNode) => {
    // 遍历树的递归函数
    function traverse(node) {
        // 检查当前节点是否为目标节点
        if (node.id === parentId) {
            debugger
            // 如果目标节点有children数组,则直接添加新节点
            // 如果没有,则先创建一个children数组
            if (!Array.isArray(node.children)) {
                node.children = [];
            }
            node.children.push(newNode); // 添加新节点
            return; // 找到后退出递归
        }

        // 如果没有找到目标节点,则继续遍历子节点(如果存在)
        if (Array.isArray(node.children)) {
            for (let i = 0; i < node.children.length; i++) {
                traverse(node.children[i]);
            }
        }
    }

    // 注意:这里假设tree是一个数组,所以需要一个一个元素的遍历
    tree.map((item, index) => {
        traverse(item);
    })

}

const getChildNodes = () => {

    const treeData = JSON.parse(JSON.stringify(oraData));
    const newNode = {id: "3-1", name: "番茄", children: []};
    addChildNode(treeData, "3", newNode);
    return treeData;
};

console.log(JSON.stringify(getChildNodes(), null, 2));

 

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值