js实现树形数据结构

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
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值