关键点:主要依赖JS中对象为引用类型的特性。
原始数据:
[
{id:1,pid: null},
{id:2,pid: 1},
{id:3,pid: null},
{id:4,pid: 2},
{id:5,pid: 3},
{id:6,pid: null},
{id:7,pid: 4}
]
目标数据:
[
{
id: 1, pid: null,
child: {
id: 2, pid: 1,
child: {
id: 4, pid: 2,
child: {id: 7, pid: 4}
}
}
},
{
id: 3, pid: null,
child: {id: 5, pid: 3}
},
{id: 6, pid: null},
]
数据解释:
将原始数据转换为目标数据后,需满足以下条件,
id 1没有pid 所以为根级
id 1包含子集 id 2,因为id 2的pid 为 1,
id 2包含子集 id 4,因为id 4的pid 为 2,
id 4包含子集 id 7,因为id 7的pid 为 4
id 3没有pid 所以为根级
id 3包含子集id 5,因为id 5的pid 为 3,
id 6没有pid 所以为根级。
代码实现及注释:
function arrayToTree(arr) {
// 定义目标数组
let obj = []
// 循环原始数据
for (let i in arr) {
// 如果当前索引值的pid为空,那么就代表当前的索引值为“根级”数据,那么直接push到目标数组里
if (!arr[i].pid) {
obj.push(arr[i])
} else {
/**
* 当前索引值的pid不为空时,
* 因为当前的pid就相当于当前元素上一级的id
* 所以要找到原始数据中 哪个item的id等于当前的pid,
* 假设我们找到的元素叫item,那么item就是当前索引值的父级
* 所以item.child 就等于当前的索引值。
* 当我们在原始数据中心找到对应的item,为其设置了child后
* 目标数组obj中对应的item也会同时修改,因为JS中对象的为引用类型,一个地方修改,所有引用的地方都修改
*/
let item = arr.find(element => element.id === arr[i].pid)
item.child = arr[i]
}
}
return obj
}