JavaScript中将数组转化成树的几种方法

后端接口返回的数据一般是平铺的数组结构,而不会是树形结构,例如下面的平铺数组结构:

data = 
[
  {id:"01", name: "张大大", pid:"", job: "项目经理"},
  {id:"02", name: "小亮", pid:"01", job: "产品leader"},
  {id:"03", name: "小美", pid:"01", job: "UIleader"},
  {id:"04", name: "老马", pid:"01", job: "技术leader"},
  {id:"05", name: "老王", pid:"01", job: "测试leader"},
  {id:"06", name: "老李", pid:"01", job: "运维leader"},
  {id:"07", name: "小丽", pid:"02", job: "产品经理"},
  {id:"08", name: "大光", pid:"02", job: "产品经理"},
  {id:"09", name: "小高", pid:"03", job: "UI设计师"},
  {id:"10", name: "小刘", pid:"04", job: "前端工程师"},
  {id:"11", name: "小华", pid:"04", job: "后端工程师"},
  {id:"12", name: "小李", pid:"04", job: "后端工程师"},
  {id:"13", name: "小赵", pid:"05", job: "测试工程师"},
  {id:"14", name: "小强", pid:"05", job: "测试工程师"},
  {id:"15", name: "小涛", pid:"06", job: "运维工程师"}
]

这样的数据可以直接在table中使用,但是不能直接在tree组件中使用,需要我们做一些转换。

first

function arrToTree(data) {
      // 将一级人员找出来
      const res = data.filter(item => item.id === '01')
      // 将一级人员对应的二级人员找出来
      const ress = data.filter(item => item.pid === '01')
      // 定义树状结构
      const treedate = [
        // 一级人员架构层  
        {
          label: res[0].job + '-' + res[0].name,
          children: []
        }
      ]

      for (let index = 0; index < ress.length; index++) {
        // 将一级人员对象提取出来
        const element = ress[index];
        // 将pid和id相同的三级人员数组找出来
        const rep = data.filter(item => item.pid === element.id)
        // 二级人员架构层
        const ref = {
          label: element.job + '-' + element.name,
          children: []
        }
        for (let i = 0; i < rep.length; i++) {
          // 再次for循环把三级人员对象拿出来
          // 将其push进二级人员的children数组中
          ref.children.push(rep[i])
        }
        // 再把二级人员架构层放进一级数组中
        treedate[0].children.push(ref)
        console.log(ref);
      }
      console.log(treedate)
    }

    arrToTree(data)

second

/**
 * 把平铺的数组结构 ---> tree
 *
 * [
 *  {id:"01", pid:"",   "name":"老王" },
 *  {id:"02", pid:"01", "name":"小张" },
 *  {id:"03", pid:"02", "name":"小小张" },
 *  {id:"04", pid:"",   "name":"老陈" }
 * ]
 * 上面的结构说明: 老王是小张的上级
 * [
 *  {id:"01", pid:"",   "name":"老王",children:[{id:"02", pid:"01", "name":"小张",children:[{id:"03", pid:"02", "name":"小小张" }] }] },
 *  {id:"02", pid:"01", "name":"小张" },
 *  {id:"03", pid:"02", "name":"小小张" },
 *  {id:"04", pid:"",   "name":"老陈" children:[]}
 * ]
 */
export function tranListToTreeData(arr) {
  const newArr = []
  // 1. 构建一个字典:能够快速根据id找到对象。
  const map = {}
  // {
  //   '01': {id:"01", pid:"",   "name":"老王",children: [] },
  //   '02': {id:"02", pid:"01", "name":"小张",children: [] },
  // }
  arr.forEach(item => {
    // 为了计算方便,统一添加children
    item.children = []
    // 构建一个字典
    const key = item.id
    map[key] = item
  })

  // 2. 对于arr中的每一项
  arr.forEach(item => {
    const parent = map[item.pid]
    if (parent) {
      //    如果它有父级,把当前对象添加父级元素的children中
      parent.children.push(item)
    } else {
      //    如果它没有父级(pid:''),直接添加到newArr
      newArr.push(item)
    }
  })

  return newArr
}

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值