把平铺的数组结构转成树形结构 Array --> Tree

本文介绍把平铺的数组转成数形数组的两种方法,分别是非递归和递归方法,包含代码和具体的推演过程

我们这里的平铺数组有三个属性:id、pid、name;其中pid决定着这个对象的父级,id决定着这个对象的子级,口有阐述可能难以表达清楚,我们看一下一个简单的小例子:

 [
   {id:"01", pid:"", name:"老王" }, // 没有pid代表没有父级,这个对象是顶级
   {id:"02", pid:"01", name:"小张" } 
 ]
 // 上面的结构说明: 老王是小张的上级

一、非递归方法:

  • 优点是相对来说更好了解,缺点是会改变原数组
// 把平铺的数组 转成 树形结构
const function arrryToTree(arr) {
  // 1. 定义两个变量
  const treeList = [] // 树状数据数组
  const map = {} // 存储映射关系

  // 2. 建立一个映射关系,并给每个元素补充children属性,key是id值,value是对象本身
  // 映射关系: 目的是让我们能通过id快速找到对应的元素
  // 补充children:让后边的计算更方便
  arr.forEach(item => {
    if (!item.children) {
      item.children = []
    }
    map[item.id] = item
  })

  // 3. 对于每一个元素来说,先找它的上级
      // 如果能找到,说明它有上级,则要把它添加到上级的children中去
      // 如果找不到,说明它没有上级,直接添加到 treeList
  arr.forEach(item => {
    const parent = map[item.pid]
    
    if (parent) {
      parent.children.push(item) // 如果存在上级则表示item不是最顶层的数据
    } else {
      treeList.push(item) // 如果不存在上级 则是顶层数据,直接添加
    }
  })
  return treeList // 返回
}
  • 上述代码的推衍过程
// 1. 原平铺数组对象
arr = [
        { id: '29', pid: '', name: '总裁办' },
        { id: '2c', pid: '', name: '财务部' },
        { id: '2d', pid: '2c', name: '财务核算部'},
        { id: '2f', pid: '2c', name: '薪资管理部'},
        { id: 'd2', pid: '', name: '技术部'},
        { id: 'd3', pid: 'd2', name: 'Java研发部'}
      ]      
 
// 2. 将id作用key建立映射关系 并补充children属性
treeList: []
map: {
  '29': { id: '29', pid: '', name: '总裁办', children:[] },
  '2c': { id: '2c', pid: '', name: '财务部', children:[] }
  '2d': { id: '2d', pid: '2c', name: '财务核算部', children:[] },
  '2f': { id: '2f', pid: '2c', name: '薪资管理部', children:[] },
  'd2': { id: 'd2', pid: '',  name: '技术部', children:[] },
  'd3': { id: 'd3', pid: 'd2', name: 'Java研发部', children:[] }
}
 
// 3. 根据pid判断有无上级 生成树状数组
treeList: [
  { id: '29', pid: '', 'name': '总裁办' }
  { id: '2c', pid: '', 'name': '财务部', children:[{ id: '2d', pid: '2c', 'name': '财务核算部'},{ id: '2f', pid: '2c', 'name': '薪资管理部'} }
  { id: 'd2', pid: '', 'name': '技术部', children:[{ id: 'd3', pid: 'd2', 'name': 'Java研发部'}]}
]

 二、递归方法

  • 优点是不会改变原数组
function arrryToTree(arr,pid=''){
// 在list中根据pid来找元素
let treeList = []
// 过滤出来pid=''的就是顶层
treeList = arr.filter(item => item.pid === pid)
// 在通过循环加递归的方法将第二层和第三层放入到children中
treeList.forEach(item => {
   item.children = arrryToTree(arr,item.id)
})
    return treeList
}
  • 上述代码的推衍过程
// 1. 原平铺数组对象
arr = [
        { id: '29', pid: '', name: '总裁办' },
        { id: '2c', pid: '', name: '财务部' },
        { id: '2d', pid: '2c', name: '财务核算部'},
        { id: '2f', pid: '2c', name: '薪资管理部'},
        { id: 'd2', pid: '', name: '技术部'},
        { id: 'd3', pid: 'd2', name: 'Java研发部'}
      ]      
 
// 2. 根据pid过滤出顶层
treeList: [
    { id: '29', pid: '', name: '总裁办' },
    { id: '2c', pid: '', name: '财务部' },
    { id: 'd2', pid: '', name: '技术部'},
]
 
// 3. 通过循环,将pid===treeList中id的对象push到children中
treeList: [
  { id: '29', pid: '', 'name': '总裁办' }
  { id: '2c', pid: '', 'name': '财务部', children:[{ id: '2d', pid: '2c', 'name': '财务核算部'},{ id: '2f', pid: '2c', 'name': '薪资管理部'} }
  { id: 'd2', pid: '', 'name': '技术部', children:[{ id: 'd3', pid: 'd2', 'name': 'Java研发部'}]}
]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值