把平铺的数组结构转成树形结构 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
    评论
树形结构转化成平铺结构深度优先遍历是指将树形结构的数据展开为一个扁平化的数组,同时保留节点之间的层级关系。这个过程通常可以使用深度优先遍历算法来实现。 以下是一个使用 JavaScript 实现树形结构转化成平铺结构深度优先遍历的示例代码: ``` function flattenTree(tree, level = 0) { const result = []; if (!tree) { return result; } const { id, name, children } = tree; result.push({ id, name, level, }); if (children && children.length > 0) { children.forEach(child => { const childResult = flattenTree(child, level + 1); result.push(...childResult); }); } return result; } ``` 其中,`tree` 参数表示树形结构的根节点,`level` 参数表示当前节点所处的层级。函数会递归遍历每个节点,并将它们展开为一个扁平化的数组,同时记录每个节点所处的层级。 使用示例如下: ``` const tree = { id: 1, name: 'A', children: [ { id: 2, name: 'B', children: [ { id: 3, name: 'C', children: null, }, { id: 4, name: 'D', children: null, }, ], }, { id: 5, name: 'E', children: [ { id: 6, name: 'F', children: null, }, { id: 7, name: 'G', children: null, }, ], }, ], }; const result = flattenTree(tree); console.log(result); ``` 输出结果为: ``` [ { id: 1, name: 'A', level: 0 }, { id: 2, name: 'B', level: 1 }, { id: 3, name: 'C', level: 2 }, { id: 4, name: 'D', level: 2 }, { id: 5, name: 'E', level: 1 }, { id: 6, name: 'F', level: 2 }, { id: 7, name: 'G', level: 2 } ] ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值