数组与数结构互转
- array2tree
- tree2array
数组转树结构 array2tree
js
const arrayToTree = (array) => {
const hashMap = {}
let result = []
array.forEach((it) => {
const { id, pid } = it
// 不存在时,先声明 children 树形
// 这一步也有可能在下面出现
if (!hashMap[id]) {
hashMap[id] = {
children: []
}
}
hashMap[id] = {
...it,
children: hashMap[id].children
}
// 处理当前的 item
const treeIt = hashMap[id]
// 根节点,直接 push
if (pid === 0) {
result.push(treeIt)
} else {
// 也有可能当前节点的父父节点还没有加入 hashMap,所以需要单独处理一下
if (!hashMap[pid]) {
hashMap[pid] = {
children: []
}
}
// 非根节点的话,找到父节点,把自己塞到父节点的 children 中即可
hashMap[pid].children.push(treeIt)
}
})
return result
}
// 测试
const data1 = [
// 注意这里,专门把 pid 为 1 的元素放一个在前面
{ id: 2, name: '部门 2', pid: 1 },
{ id: 1, name: '部门 1', pid: 0 },
{ id: 3, name: '部门 3', pid: 1 },
{ id: 4, name: '部门 4', pid: 3 },
{ id: 5, name: '部门 5', pid: 4 },
{ id: 7, name: '部门 7', pid: 6 }
]
console.log(JSON.stringify(arrayToTree(data1), null, 2))
树结构转数组 tree2array
js
const tree2list = (tree) => {
let list = []
let queue = [...tree]
while (queue.length) {
// 从前面开始取出节点
const node = queue.shift()
const children = node.children
// 取出当前节点的子节点,放到队列中,等待下一次循环
if (children.length) {
queue.push(...children)
}
// 删除多余的 children 树形
delete node.children
// 放入列表
list.push(node)
}
return list
}
// 测试
const data2 = [
{
id: 1,
name: '部门 1',
pid: 0,
children: [
{
id: 2,
name: '部门 2',
pid: 1,
children: []
},
{
id: 3,
name: '部门 3',
pid: 1,
children: [
{
id: 4,
name: '部门 4',
pid: 3,
children: [
{
id: 5,
name: '部门 5',
pid: 4,
children: []
}
]
}
]
}
]
}
]
console.log(tree2list(data2))