一维数组转tree数据结构 平面数据转多维数据

现有一个一维数组  对应 学校  班级  学生

​
    let inputArr = [

        { id: 2, val: "班级1", parentId: 1, },

        { id: 4, val: "班级3", parentId: 1, },

        { id: 5, val: "学生1", parentId: 2, },

        { id: 1, val: "学校", },

        { id: 6, val: "学生2", parentId: 3 },

        { id: 3, val: "班级2", parentId: 1, },

        { id: 7, val: "学生3", parentId: 4 },

    ];

​

   需要转换成 :

let output = {
        id: 1,
        val: "学校",
        children: [ 
               {id: 2,
                val: "班级1",
                children: [{ id: 5, val: "学生1"}]},
               {id: 3,
                val: "班级2",
                children: [{ id: 6, val: "学生2"}],
               },
               {id: 4,
                val: "班级3",
                children: [{ id: 7, val: "学生3"}], 
                },
  ],};

解决方案:

  function getTreeArr(floatArr) {
        if (!Array.isArray(floatArr)) throw new Error('参数错误')
        const float = JSON.parse(JSON.stringify(floatArr))//深拷贝数组  注意json的局限性
        const result = []

        const map = {}//储存对象数组  使用浅拷贝引用地址指向同一目标的特性
        //最开始使用的是  new Map()数据结构 所以对象名取map  实际效果差不多

        float.forEach(item => {
            item.children = []
            !map[item.id] && (map[item.id] = item)//将数据拷贝进对象里面
        })

        float.forEach(item => {
            if (map[item.parentId]) {//父id对应id
                map[item.parentId].children.push(item)//浅拷贝的引用地址
            }
            !item.parentId && result.push(item)//没有父id的是最上层数据添加进结果数组
        })

        return result
    }
    console.log(getTreeArr(inputArr), inputArr);

  //此题是  parentId对应id   .扩展一下  可以给函数新增两个参数  用于对应关系 
  
  //还可以新增一个回调参数  做其他用处

比较老土的回调函数写法

  function splitArr(arr) {
    let result = []
    arr.forEach(i => {
      if (!i.parentId) result.push(i) //先添加初始值 没有parentId
    })

    const parentIdArr = [...new Set(arr.map(i => i.parentId))] //提取parentId,去重

    function inside(filterArr, pid) {
      const _result = filterArr.filter(item => item.parentId === pid).map(i => {
        delete i.parentId
        return i
      }) //过滤出来一个数组,这就是需要的数据,但是还需要挂载子数组

      const newArr = filterArr.filter(function (obj1, index) { //过滤掉已经使用的数组,剩下还没有分配的数组
        return !_result.find(function (obj2) {
          return obj1.id === obj2.id
        })
      })
      const _parentIdArr = [...new Set(newArr.map(i => i.parentId))]

      _parentIdArr.length && _result.forEach(item => { //剩下的数组还有内容就继续执行
        if (_parentIdArr.some(i => i === item.id)) { //如果有检测到父id就执行一次回调函数
          item.children = inside(newArr, item.id)
        }
      })
      return _result
    }

    result.forEach(item => {
      if (parentIdArr.some(i => i === item.id)) { //如果父id数组有,就调用这个方法
        item.children = inside(arr.filter(i => i.parentId), item.id)
      }
    })

    return result.length === 1 ? result[0] : result
  }
  console.log(splitArr(inputArr));

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值