前言
前几天在网上看到一篇文章,说的是中高级前端必须会的几个技能和题目,里面刚好一个扁平数据结构转 Tree 的问题。
在前端开发时,这种问题我们会遇到的不多,大部分都是后端处理好之后再传给我们的,但是我们也要自己学会,并且掌握,毕竟我们也是有追求的嘛😏
废话不多说,直接上菜!
题目:
1、根据数组中的元素,每个元素的 pid 根节点,然后把它挂载到 id(父节点) 等于 pid(子节点)的元素 children 上
let arr = [
{id: 1, name: '部门1', pid: 0},
{id: 2, name: '部门2', pid: 1},
{id: 3, name: '部门3', pid: 1},
{id: 4, name: '部门4', pid: 3},
{id: 5, name: '部门5', pid: 4},
]
2、希望得到的数据:
[
{
"id": 1,
"name": "部门1",
"pid": 0,
"children": [
{
"id": 2,
"name": "部门2",
"pid": 1,
"children": []
},
{
"id": 3,
"name": "部门3",
"pid": 1,
"children": [
// 结果 ,,,
]
}
]
}
]
思路:
1、这个问题所考的是对 Tree、原型链、指针(类似)的理解,因为要变成树状结构,而且要将所有的元素放到 Tree 的节点上,并且输出根节点就能得到所有的节点
2、先把数组转成 Map 类型,然后将数组类的数据以键值对的方式放入,key 是 id,value 是对象,在 value 中再添加一个 children: [] 的属性
3、创建一个 空对象vObj,遍历 Map,去比对当前 对象 是否有 pid,不存在就是根节点,将它赋值给之前创建的 空对象vObj,存在则根据当前对象的 pid 获取 父元素的对象,并且把当前对象放到父元素对象中的children里面
4、最后 return 空对象vObj 即可
直接上代码
let arr = [
{ id: 3, name: '部门3', pid: 1 },
{ id: 1, name: '部门1', pid: 0 },
{ id: 2, name: '部门2', pid: 1 },
{ id: 5, name: '部门5', pid: 4 },
{ id: 4, name: '部门4', pid: 3 },
{ id: 9, name: '部门9', pid: 3 },
{ id: 7, name: '部门7', pid: 1 },
{ id: 8, name: '部门8', pid: 2 },
{ id: 6, name: '部门6', pid: 4 },
]
function deepTree(arr) {
const vMap = new Map();
arr.forEach(item => {
vMap.set(item.id, Object.assign(item, { children: [] }));
});
let vObj = {};
vMap.forEach(item => {
if (vMap.has(item.pid)) {
const vParent = vMap.get(item.pid);
vParent.children.push(item);
} else {
vObj = vMap.get(item.id);
}
})
return vObj
}
希望我的思路能给小伙伴们提供一些参考!