利用非递归方式实现数组转化成树形结构(1)

3,511 阅读1分钟

前言

在工作中,我们经常需要用到树形结构的数据,在这个时候,我们要么叫后端处理一下,响应数据的时候就把数据处理好.

如果后端不给我们处理,打又打不过的时候,我们就只能自己处理一下,话不多说,直接上代码

利用非递归方式数组转数

<script>

  /**
  * 把平铺的数组结构转成树形结构
  */
  const 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研发部' }
  ]

  function tranListToTreeData(list) {
    // 1. 定义两个中间变量
    const treeList = [],  // 最终要产出的树状数据的数组
      map = {}        // 存储映射关系


    // 2. 建立一个映射关系,并给每个元素补充children属性.
    // 映射关系: 目的是让我们能通过id快速找到对应的元素
    // 补充children:让后边的计算更方便
    list.forEach(item => {
      if (!item.children) {
        item.children = []
      }
      map[item.id] = item
    })
    //  {
    //    "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. 循环
    list.forEach(item => {
      // 对于每一个元素来说,先找它的上级
      //    如果能找到,说明它有上级,则要把它添加到上级的children中去
      //    如果找不到,说明它没有上级,直接添加到 tree3List
      const parent = map[item.pid]
      if (parent) {
        parent.children.push(item)
      } else {
        treeList.push(item)
      }
    })
    // 4. 返回出去
    return treeList
  }

  const treeList = tranListToTreeData(arr)
  console.log(treeList);
</script>
  • 转化后的数据结构

数组转树利用非递归.png 通过这种方式,我们可以很好的实现数组转树,同时也要注意下,在上面代码中,原数组也被影响到了,因为是浅拷贝,每一项都添加了children属性

Snipaste_2021-10-19_19-35-34.png

  • 补充:刚才有朋友说不用递归只能做到两层树状,所以直接上代码

在这里我改了一下数据结构,如下,有三层

Snipaste_2021-10-20_14-44-53.png 输出结果:

代码输出.png 结论: 使用这种方法也是可以做到多层嵌套的