什么是树形数据
有一些业务场景在描述主体关系的时候必须使用树形数据,比如:我们常见的家庭成员关系图,公司里的组织架构等,要描述这样的业务场景,与之对应的,我们就得给出树形结构的数据
有时候,后端接口返回的数据一般是平铺的数组结构,而不会是树形结构,例如下面的平铺数组结构:
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: "运维工程师"}
]
这就需要我们将这样的平铺数据结构转换为树结构,具体转换如下:
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)