话不多说,直接上代码吧
1.首先原有的数组数据
let data = [{
id: 0,
pid: -1,
name: 'haha'
},{
id: 1,
pid: 0,
name: 'a'
}, {
id: 2,
pid: 0,
name: 'b'
}, {
id: 3,
pid: 1,
name: 'c'
}, {
id: 4,
pid: 3,
name: 'd'
}, {
id: 5,
pid: 3,
name: 'e'
}, {
id: 6,
pid: 4,
name: 'f'
}]
2.想要转换成的数据类型
let treeData = {
id: 0,
pid: -1,
name: 'haha',
children: [{
id: 1,
pid: 0,
name: 'a',
children: [{
id: 3,
pid: 1,
name: 'c',
children: [{
id: 4,
pid: 3,
name: 'd',
children: [{
id: 6,
pid: 4,
name: 'f',
children: []
}]
},{
id: 5,
pid: 3,
name: 'e',
children: []
}]
}]
},{
id: 2,
pid: 0,
name: 'b',
children: []
}]
}
3实现转换的步骤
function arrayToTree(data) {
//1.先验证data是否是数组类型
let result = [];
if(!Array.isArray(data)) return result;
//2.观察一下,其实就是这种数据结构的嵌套
//{
// id: 1,
// pid: 0,
// name: 'a',
// children:[]
// }
//3.第一步转换,建立id和这个元素的键值关系,方便一步找到这个元素
//比如我想要找到id为1的元素,就需要去遍历数组,
//这样转换之后只需要map[id]就可以了
let map = {};
data.forEach(item => {
map[item.id] = item;
})
//4.这时候你需要知道深浅拷贝,上面的把item赋值给map[item.id],其实就是浅拷贝,
//可以理解成只要map[item.id]变化,相应的data也会变化
//5.最主要的一步
data.forEach(item => {
//如果map[item.pid]不是undefined,说明这个元素有父节点,父节点就是map[item.pid]
//如果是,说明这个item已经是根节点了
if(map[item.pid]){
//怎么解释这一步呢。。。
(map[item.pid].children || map[item.pid].children=[]).push(item)
}else{
result.push(item)
}
})
}
附上另一个一次循环的方法treefy