数组转换树

212 阅读2分钟

数组转换树

什么是树形数据

有一些业务场景在描述主体关系的时候必须使用树形数据,比如:我们常见的家庭成员关系图,公司里的组织架构等,要描述这样的业务场景,与之对应的,我们就得给出树形结构的数据

image.png

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

[
{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: "运维工程师"}
]

这就需要我们将这样的平铺数据结构转换为树结构,具体转换如下:

function arrToTree(data) {

  // 先把传进来的数据的 name 修改为 label 再删除 name
  data.map(item => {
    item.label = item.name
    delete item.name
  })
  // 声明空数组 接收最后的结果
  let arr = []
  // 定义空对象 接收每个人的信息并准备划分层级
  let obj = {}
  // 判断传送进来的值是否为数组,可以使用Array.isArray()方法判断,也可以用instanceof Array 进行判断
  if (!(data instanceof Array)) {
    return arr
  }
  // 循环 data 先把所有的数据放进一个对象里
  data.forEach(item => {
    obj[item.id] = item
  })
  // 定义遍历删除id、job、pid的方法
  function del(del) {
    return del.forEach(i => {
      delete i.id
      delete i.job
      delete i.pid
    })
  }
  data.forEach(item => {
    if (obj[item.pid]) {
      if (obj[item.pid].children) {
        obj[item.pid].children.push(item)
        // 遍历删除id、job、pid
        del(obj[item.pid].children)
      } else {
        ;(obj[item.pid].children = []).push(item)
        del(obj[item.pid].children)
      }
    } else {
      arr.push(item)
      del(arr)
    }
  })
  return arr
}
// 目标:
const treeData = arrToTree(data)
console.log(treeData)