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

news2025/1/9 1:42:11

一 数据源

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

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));

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1837095.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c++参考std::string自己设计类hstring

目录 一、前言 二、设计需求 三、设计思想 1.功能一 1.功能二 四、设计过程 1.类hstring搭建 2. 实现有参构造函数 3. 实现副本构造函数 4.完整代码 五、结束语 一、前言 在c中有很多的库&#xff0c;但是在有些时候呢&#xff0c;我们一定要学会自己去设计库&#…

游戏服务器研究一:bigworld 开源代码的编译与运行

1. 前言 bigworld 已经开源了它的代码&#xff0c;而我对于大世界的 scale 很感兴趣&#xff0c;所以就尝试把代码跑起来研究。但是&#xff0c;整个过程比我原先预想的复杂得多。 虽然能找到一些官方的帮助文档&#xff0c;但这些文档要么过旧&#xff0c;要么过于详尽&…

SpringBoot + Maven 项目的创建

文章目录 1、Maven2、SpringBoot3、二者之间的联系4、项目的创建 在创建项目之前&#xff0c;肯定要知道他们之间的区别 1、Maven maven是一个跨平台的项目管理工具。它是Apache的一个开源项目&#xff0c;主要服务于基于Java平台的项目构建、依赖管理和项目信息管理。 比如说…

贪吃蛇游戏代码(C语言项目)

本篇仅提供C语言代码&#xff0c;详细讲解在这篇博客&#xff1a;C语言&#xff1a;贪吃蛇游戏&#xff08;从0开始完整版&#xff09;-CSDN博客 1、运行演示 QQ2024618-155655 2、代码构成&#xff08;vs编译器&#xff09; 3、C语言代码 3.1 头文件Snake.h #pragma once #i…

存储文件夹下所有.cpp和.h的代码到对应的txt文件里

最近大半年刷了160多天的题&#xff0c;每次刷的时候都要新建一个VS文件&#xff0c;所以文件内存太大了&#xff0c;又舍不得删&#xff0c;就用ai整了一个脚本&#xff0c;可将当前路径下的所有文件里的.cpp和.h文件储存到相应名字的txt文件里&#xff0c;若文件夹下还有文件…

概率论拾遗

条件期望的性质 1.看成f(Y)即可 条件期望仅限于形式化公式&#xff0c;用于解决多个随机变量存在时的期望问题求解&#xff0c;即 E(?)E(E(?|Y))#直接应用此公式条件住一个随机变量&#xff0c;进行接下来的计算即可 定义随机变量之间的距离为&#xff0c;即均方距离 随机…

k8s集群新增计算节点使用华为iscsi存储创建的pvc存储挂载报错:FailedMount

背景&#xff1a; 因公司业务需求的增长&#xff0c;导致kubernetes集群测试环境的计算节点资源不够使用了&#xff0c;这时候就申请了几台服务器加入到kubernetes集群中&#xff0c;因为维护的kubernetes集群的对接华为了iscsi存储&#xff0c;通过storageclass组件来创建pvc存…

LangChain入门学习笔记(四)—— Model I/O之LLMs

Prompts输入大模型应用后&#xff0c;下一个重要的处理组件就是LLM或者Chat Model&#xff0c;在这里大模型根据提示语产生相应内容&#xff0c;本章主要介绍LLM。 LangChain不定义自己的LLMs&#xff0c;但是它提供标准接口。由其他的LLM提供商&#xff08;比如OpenAI、Coher…

服务器数据恢复—NTFS文件系统下双循环riad5数据恢复案例

服务器存储数据恢复环境&#xff1a; EMC CX4-480存储&#xff0c;该存储中有10块硬盘&#xff0c;其中有3块磁盘为掉线磁盘&#xff0c;另外7块磁盘组成一组RAID5磁盘阵列。运维人员在处理掉线磁盘时只添加新的硬盘做rebuild&#xff0c;并没有将掉线的硬盘拔掉&#xff0c;所…

CleanMyMac X for Mac系统优化垃圾清理软件卸载 工具(小白轻松上手,简单易学)

Mac分享吧 文章目录 效果一、准备工作二、开始安装1、双击运行软件&#xff0c;将其从左侧拖入右侧文件夹中&#xff0c;等待安装完毕2、启动台显示软件图标&#xff0c;表示安装成功 三、运行测试1、打开软件&#xff0c;配置2、授权&#xff0c;允许完全磁盘访问 安装完成&a…

CCAA质量管理【学习笔记】​​ 备考知识点笔记(六)质量改进系统方法与工具

第七节 质量改进系统方法与工具 1 质 量 改 进 方 法 概 述 可以说几乎每种质量管理领域的方法与工具都可以用于质量改进&#xff0c;但是一个组织在改进的整体推进中&#xff0c;往往不是采用单一的方法&#xff0c;会涉及多种改进的工具和手段&#xff0c;并依据一定的模式…

原来设计师都在这些网站找素材、灵感的

设计师可以去哪些网站找设计素材和灵感&#xff0c;收藏好这几个网站&#xff0c;设计必备&#xff0c;提升审美的好帮手。 设计素材网站 1、菜鸟图库 菜鸟图库-免费设计素材下载 菜鸟图库一个可以免费下载设计素材的网站&#xff0c;我推荐过很多次&#xff0c;主要是站内素材…

职业教育app开发,因为热爱,所以不断向前

从学校毕业后&#xff0c;面对愈来愈严重的职场内卷&#xff0c;人们不仅没有对学习产生丝毫懈怠&#xff0c;反而越来越注重职业教育。随着科技与经济的不断发展&#xff0c;线上职业教育app应运而生&#xff0c;以其快捷、高效的特点被越来越多人所选择。 一&#xff0e; 职…

【QT教程】使用qcustomplot完成对图像的拖动、框选缩放、自动缩放、游标等操作

目录 1.Qt 配置qcustomplot2.图像拖拽功能3.图像框选放大4.曲线自动缩放5.图像游标6.【完整代码】将曲线抽象成一个类&#xff0c;以便复用 1.Qt 配置qcustomplot 首先下载qcustomplot官网&#xff08;qcustomplot下载地址&#xff09;下载最近的源码&#xff0c;我用的是2.1.…

在执行sudo apt update时提示“sudo:aapt:找不到命令”

文章目录 1、问题引入2、问题解决区别 1、问题引入 在干净的虚拟机环境发现执行不了“sudo apt update”命令 2、问题解决 我们知道linux有许多的系统&#xff0c;例如CentOS、Ubuntu等&#xff0c;而apt和yum都是linux的包管理工具&#xff0c;可以安装、升级和删除软件。那…

经纬恒润EAS.HSM:驱动硬件信息安全

概述 HSM&#xff08;Hardware Security Module&#xff09;硬件安全模块&#xff0c;是一种用于保护和管理强认证系统所使用的密钥&#xff0c;并同时提供相关密码学操作的计算机硬件设备。 HSM 在汽车信息安全中扮演着至关重要的角色。随着汽车智能化和网联化的快速发展&am…

航空电子设备 MIL-STD-1553 收发器 HI-1573 / HI-1574

Holt集成电路通过真正的单芯片双3.3V收发器继续支持MIL-STD-1553数据总线。新型HI-1573采用成熟的设计技术和最新的模拟CMOS技术&#xff0c;当以100&#xff05;占空比进行传输时&#xff0c;仅消耗340mW的功率&#xff0c;同时仍可为总线提供所需的功率。通过将RXENA或RXENB设…

想体验“时光倒流”吗?文件时光机——可道云teamOS,历史版本管理,随时回溯版本

大家在工作中&#xff0c;遇到过的最奔溃的事情是什么&#xff1f; 是工作没有做好&#xff0c;还是客户要求太离谱&#xff1f; 不知道大家有没有过这样的经历&#xff0c;根据客户要求改方案、改稿子&#xff0c;改了一版又一版&#xff0c;结果客户说还是最初版本更好………

C++ 48 之 继承的基本语法

#include <iostream> #include <string> using namespace std;// 定义一个基类&#xff0c;把公共的部分写在这里&#xff0c;以后让别的类继承即可 class BasePage{ public:void header(){cout << "公共的头部"<< endl;}void footer(){cout…

打造精致UI界面:字体设计的妙招

字体设计是UI设计的关键模块之一。字体设计是否有效可能直接实现或破坏整个UI界面。那么&#xff0c;界面设计的字体设计有哪些规范呢&#xff1f;如何设计细节字体&#xff1f;本文将解释字体设计规范的可读性、可读性和可用性&#xff0c;并介绍UI界面中的字体设计技巧。 如…