js树形数组遍历练习,扁平化、格式化、获取节点父级

news2024/11/26 8:24:49

1.树形数组扁平化

数组扁平化的方式很多,这里主要是用递归处理,除此之外还有正则、扩展运算符等等

    const list = [
        {name:'1',id:'1',children:[
            {name:'11',id:'11',children:[{name:'111',id:'111'}]},
            {name:'12'},
        ]},
        {name:'2',id:'2',children:[
            {name:'21',id:'21',children:[{name:'221',id:'221'}]},
            {name:'22',id:'22'},
        ]},
    ]
    // 树形数组扁平化
     const test = (arr)=>{
        const list = []
        if(arr instanceof Array){
           for (let i = 0; i < arr.length; i++) {
                const item = arr[i];
                if(item.children && item.children.length>0){
                  list.push(...test(item.children))//将每一层的结果push到list
                }
                delete item.children//视情况而定是否删除children属性
                list.push(item)
            }
        }
        return list
    }
    console.log(test(list,'扁平化'));

2.树形数组格式化(修改节点key值) 

使用for改变原数组的方式

    // 树形数组递归格式化数组:使用for(改变原数组)
    const format = (arr)=>{
        if(arr instanceof Array){
            for (let i = 0; i < arr.length; i++) {
                const ele = arr[i];
                ele.label = ele.name;
                ele.value = ele.id;
                delete ele.name;
                delete ele.id;
                if(ele.children && ele.children.length>0){
                    format(ele.children);
                }
            }
            return arr
        }
    }

使用能生成新数组的方式:

    // 树形数组递归格式化数组:使用forEach(不改变原数组)
    const format2 = (arr)=>{
        if(arr instanceof Array){
           return  arr.map(item => {
                item.label = item.name;
                item.value = item.id;
                delete item.name;
                delete item.id;
                if(item.children && item.children.length>0){
                    format2(item.children);
                }
                return item
            });
        }
    }

 3.获取树形数组中某个节点的所有父级节点

 这个方式需要熟悉函数在堆栈中的调用顺序才好理解否则理解起来有点绕

    const list = [
        {name:'1',id:'1',children:[
            {name:'11',id:'11',children:[{name:'111',id:'111'}]},
            {name:'12'},
        ]},
        {name:'2',id:'2',children:[
            {name:'21',id:'21',children:[{name:'221',id:'221'}]},
            {name:'22',id:'22'},
        ]},
    ]
const getParentId = (arr,id)=>{
        for (let i = 0; i < arr.length; i++) {
            const item = arr[i]
            if(item.id==id){
                return [item]
            }
            if(item.children && item.children.length>0){
                let node = getParentId(item.children,id);
                //当当前item的有返回数组时则表示已经找到目标(id)节点item二级,node三级
                // node表示目标节点,而当前item则是第二次执行getParentId函数的item,因为第三次调用的getParentId函数在堆栈中被(return)去除掉了
                if(node!==undefined){
                    return node.concat(item);//这里每return一次堆栈就会去除一次最顶层函数
                }
            }
        }
    }
    // js函数调用堆栈:js每执行一个函数就会往堆栈放一个函数,如果函数执行完或者return之后就会从堆栈剔除,堆栈遵循先进后出的顺序
    // 执行顺序:(每执行一次函数,往堆栈里面放一个函数)
    // 执行函数getParentId(),往堆栈里面放一个函数,
    // 第一遍代码执行到let node = getParentId(item.children,id)的时候,执行递归于是跳到函数getParentId的开头执行第二遍,再放一个函数在堆栈
    // 第二次执行到let node = getParentId(item.children,id)时候跟第一次一样继续执行递归函数getParentId,再放一个函数在堆栈
    // 第三次执行的时候item.id==id,于是return掉当前的函数,
    // 而当前是第三次执行的函数,return之后当前函数就从堆栈中去除了,堆栈只剩两个函数了(第一次执行的getParentId函数跟第二次执行getParentId函数)
    //  于是继续执行第二个getParentId,它不会从头开始而是从第二次递归后面那里(因为之前在这结束调转到函数开头的,所以继续从这里执行)开始执行,
    // 发现node!==undefined成立于是将第二个getParentId函数return掉,从堆栈中去除
    // 去除之后堆栈中只剩第一次执行的getParentId函数,此时不会从头开始执行,而是继续在第一次递归调用那里往后执行(因为之前在这结束调转到函数开头的,所以继续从这里执行),最终返回函数的结果
    
    

 

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

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

相关文章

【Redis】set常用命令集合间操作内部编码使用场景

文章目录 前置知识常见命令SADDSMEMBERSSISMEMBERSCARDSPOPSMOVESREM 集合间操作SINTERSINTERSTORESUNIONSUNIONSTORESDIFFSDIFFSTORE 命令小结内部编码测试内部编码 使用场景 前置知识 集合类型也是保存多个字符串类型的元素的&#xff0c;但和列表类型不同的是&#xff0c;在…

目标检测回归损失函数(看情况补...)

文章目录 L1 loss-平均绝对误差(Mean Absolute Error——MAE)L2 loss-均方误差(Mean Square Error——MSE)Smooth L1 LossMAE、MSE、Smooth L1对比IoU LossGIoU LossDIoU Loss、CIoU LossE-IoU Loss、Focal E-IoU LossReferenceL1 loss-平均绝对误差(Mean Absolute Error——…

kubernetes helm

一、helm Helm是Kubernetes 应用的包管理工具&#xff0c;主要用来管理 Charts&#xff0c;类似Linux系统的yum。Helm Chart 是用来封装 Kubernetes 原生应用程序的一系列 YAML 文件。可以在你部署应用的时候自定义应用程序的一些 Metadata&#xff0c;以便于应用程序的分发。…

Python算法例9 罗马数字转换为整数

1. 问题描述 给定一个罗马数字&#xff0c;将其转换为整数&#xff0c;要求返回结果的取值为1~3999。 2. 问题示例 Ⅳ→4&#xff0c;Ⅻ→12&#xff0c;ⅩⅪ→21&#xff0c;XCVI→99。 3. 代码实现 def roman_to_int(s):roman_map {I: 1, V: 5, X: 10, L: 50, C: 100, …

软件测试/校招推荐丨鼎捷软件股份有限公司岗位开放

点此获取更多相关资料 软件测试工程师 岗位职责 负责公司产品的日常测试工作&#xff1b;依据软件需求和非功能需求&#xff0c;编写测试方案和测试用例&#xff0c;设计测试脚本&#xff1b;负责服务器系统和软件的日常维护工作&#xff0c;为上线部署和运维活动提供技术支持…

Yakit工具篇:WebFuzzer模块之序列操作

简介 Web Fuzzer 序列就是将多个 Web Fuzzer 节点串联起来&#xff0c;实现更复杂的逻辑与功能。例如我们需要先进行登录&#xff0c;然后再进行其他操作&#xff0c;这时候我们就可以使用 Web Fuzzer 序列功能。或者是我们在一次渗透测试中需要好几个步骤才能验证是否有漏洞这…

VMWare中的Centos7,DHCP获取不到IP地址

Centos是通过桥接的方式连接到主机&#xff0c; 某次开机后&#xff0c;Centos中获取不到&#xff29;&#xff30;地址&#xff0c;可以先卸载主机中的VMware Bridge Protocal. 然后在VMWare中的虚拟网络编辑器中&#xff0c;还原默认设置。 重新开关centos中的网络就可以了。…

【Unity】零基础实现塔防游戏中敌人沿固定路径移动的功能

目录 场景搭建 烘焙(Bake) 敌人动作控制 脚本实现 我们知道&#xff0c;在一些塔防小游戏中&#xff0c;敌人往往会沿着给定的一条路径移动&#xff0c;我们在条路的路边会布置防御设施&#xff0c;攻击消灭敌人&#xff0c;阻止敌人到达终点。 场景搭建 我们首先新建一个…

【python海洋专题四十三】海洋指数画法--多色渐变柱状图

【python海洋专题四十三】海洋指数画法–多色渐变柱状图 图片 往期推荐 图片 【python海洋专题一】查看数据nc文件的属性并输出属性到txt文件 【python海洋专题二】读取水深nc文件并水深地形图 【python海洋专题三】图像修饰之画布和坐标轴 【Python海洋专题四】之水深…

电动自行车一车一码管理系统

一、应用介绍 针对电动车乱停乱放问题&#xff0c;通过对电动车赋码实现电动车基本信息管理、日常维护登记管理。日常巡查过程中&#xff0c;发现乱停乱放&#xff0c;微信扫码即可查看车主信息&#xff0c;可以及时播打电话通知车主&#xff0c;同时微信扫码及时登记车辆违规信…

临界资源,临界区,通信的干扰问题(互斥),信号量(本质,上下文切换问题,原子性,自身的安全性,操作)

目录 引入 概念 临界资源 临界区 干扰存在原因 互斥 信号量 引入 举例 概念 介绍 表示可用资源数 表示等待进程数 申请信号量 信号量的本质 全局变量? 共享内存? 不安全问题 -- 上下文切换 原子性 信号量自身的安全性 原子操作的意义 操作 引入 通信…

【算法练习Day42】买卖股票的最佳时机 III买卖股票的最佳时机 IV

​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;练题 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录 买卖股票的最佳时机 III买卖…

详解FreeRTOS:系统时钟节拍(进阶篇—8)

在详解FreeRTOS:FreeRTOS时间片调度(进阶篇—7)中我们讲到了时钟节拍这个概念,本篇博文将详细讲解FreeRTOS系统时钟节拍相关知识。 不管是什么系统,运行都需要有个系统时钟节拍,xTickCount 就是FreeRTOS 的系统时钟节拍计数器。每个滴答定时器中断中 xTickCount 就会加一…

第七讲:利用类事件改变对象的属性(上)

《VBA中类的解读及应用》教程【10165646】是我推出的第五套教程&#xff0c;目前已经是第一版修订了。这套教程定位于最高级&#xff0c;是学完初级&#xff0c;中级后的教程。 类&#xff0c;是非常抽象的&#xff0c;更具研究的价值。随着我们学习、应用VBA的深入&#xff0…

数据结构-栈和队列(一)

目录 1.栈 1.1 栈的概念及结构 1.2 栈的实现 初始化栈&#xff1a; 入栈&#xff1a; 判空函数&#xff1a; 出栈&#xff1a; 获取栈顶元素&#xff1a; 获取栈中有效元素的个数&#xff1a; 销毁栈&#xff1a; 完整代码&#xff1a; 测试&#xff1a; 2. 队列 …

AI 绘画 | Stable Diffusion 高清修复、细节优化

前言 在 Stable Diffusion 想要生成高清分辨率的图片。在文生图的功能里&#xff0c;需要设置更大的宽度和高度。在图生图的功能里&#xff0c;需要设置更大的重绘尺寸或者重绘尺寸。但是设置完更大的图像分辨率&#xff0c;需要更大显存&#xff0c;1024*1024的至少要电脑的空…

软磁直流测试系统电参量指标

软磁直流测试系统电参量指标 输出能力 电流范围 0 &#xff5e; 25 A 最大功率 1000 W 调节细度 0.005%*RG ① 最佳测量不确定度 0.2% 磁通测量 (磁通计) 磁通计量程 500 μWb、5 mWb、25 mWb 磁通计漂移 ( 0.05%*RG )/min或1 μWb…

“双11”近300万商家为消费者贴息,花呗分期免息成增长“利器”

今年双11&#xff0c;很多消费者发现&#xff0c;能用花呗分期免息的商品变多了&#xff0c;不光是品牌旗舰店&#xff0c;还有中小淘宝卖家&#xff0c;不少直播间里的商品&#xff0c;都能用花呗分期免息。这背后&#xff0c;是平台、商家对花呗分期免息的重视和需要。 数据…

STM32独立看门狗(IWDG)溢出时间计算

什么是IWDG&#xff1f; 独立看门狗(IWDG)由专用的低速时钟(LSI)驱动&#xff0c;即使主时钟发生故障它也仍然有效。 IWDG最适合应用于那些需要看门狗作为一个在主程序之外&#xff0c;能够完全独立工作&#xff0c;并且对时间精度要求较低的场合。 从上图我们可以看出IWDG的时…

走进黑客漏洞赏金猎人的大门

走进黑客漏洞赏金猎人的大门,了解最新的漏洞、漏洞EXP和安全技术。 自动化SQL盲注 创建Nuclei模板:该文章首先介绍了如何创建一个Nuclei模板,以利用clusterbomb方法对我们感兴趣的功能点进行有效的暴力破解。 使用GET请求:在模板中,我们只使用GET请求。其中,{}被视为替换…