js实现树形数据结构

▼ 前端 - Web 同时被 2 个专栏收录
46 篇文章 1 订阅

js实现树形数据结构

推荐大家使用这位大佬(蔚莱先森)的转化方式(5行代码,很精简)
蔚莱先森:https://blog.csdn.net/Mr_JavaScript/article/details/82817177
本人转换代码大概20行,使用双层for循环,而大佬使用filter方式,结果一致,自己有需要可以再改造

场景

后台传来的菜单数据是没有层级的,只有parentId标识,像vue中的tree table数据接收都需要有父子层级关系的数据格式,所以需要前端人员进行格式转换成有childre[ ]父子级格式的数据(那么问题来了,为什么不让后端转换好发送给前端人员呢?答案是:我是后端人员o( ̄︶ ̄)o,哈哈)

上代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    aaaaaaaaa

    <script>
        let source = [
          {id:1,parentId:0,name:"一级菜单A",rank:1},
          {id:2,parentId:0,name:"一级菜单B",rank:1},
          {id:3,parentId:0,name:"一级菜单C",rank:1},
          {id:4,parentId:1,name:"二级菜单A-A",rank:2},
          {id:5,parentId:1,name:"二级菜单A-B",rank:2},
          {id:6,parentId:2,name:"二级菜单B-A",rank:2},
          {id:7,parentId:4,name:"三级菜单A-A-A",rank:3},
          {id:8,parentId:7,name:"四级菜单A-A-A-A",rank:4},
          {id:9,parentId:8,name:"五级菜单A-A-A-A-A",rank:5},
          {id:10,parentId:9,name:"六级菜单A-A-A-A-A-A",rank:6},
          {id:11,parentId:10,name:"七级菜单A-A-A-A-A-A-A",rank:7},
          {id:12,parentId:11,name:"八级菜单A-A-A-A-A-A-A-A",rank:8},
          {id:13,parentId:12,name:"九级菜单A-A-A-A-A-A-A-A-A",rank:9},
          {id:14,parentId:13,name:"十级菜单A-A-A-A-A-A-A-A-A-A",rank:10}
      ];
      console.log(source)

    
    //第一种: filter 方式
    function setTreeData(source){
        let cloneData = JSON.parse(JSON.stringify(source))      // 对源数据深度克隆
        return  cloneData.filter(father=>{                      // 循环所有项,并添加children属性
            let branchArr = cloneData.filter(child=>father.id == child.parentId);       // 返回每一项的子级数组
            branchArr.length>0 ? father.children=branchArr : ''   //给父级添加一个children属性,并赋值
            return father.parentId==0;      //返回第一层
        });
    }
    console.log(setTreeData(source),'++++++++++++')   // 树形数据
    
    // 第二种: for in 方式
    function TreeData(source){
        let data = source     
        let oneMenu = [];
        let tempObj = {}
        for(let k in data){
            for (let i in data) { //啥也别说,先赋值一圈
                tempObj[data[i].id] = data[i]
            }
            let objParentId =  tempObj[data[k].id].parentId;//外层循环开始,获取当前对象父id
            let currentObj = tempObj[data[k].id];//获取当前对象
            if(objParentId>0){//当前对象如果不是一级菜单
                if(!(child instanceof Array))tempObj[objParentId].child = []; //如果不是数组则进行创建空数组[],防止undefined
                tempObj[objParentId].child.push(currentObj)
            }else{ //只取一级菜单,此时一级菜单中已经添加了child数组了
                oneMenu.push(currentObj)
            }
        }
        return oneMenu;
    }
    console.log(TreeData(source),'--------------')   // 树形数据


    </script>

</body>
</html>
  • 0
    点赞
  • 0
    评论
  • 3
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:编程工作室 设计师:CSDN官方博客 返回首页

打赏作者

探索丶挑战丶突破

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值