树结构转换
大约 3 分钟
树结构转换
在开发当中,我们经常会遇到树形结构的数据,有时我们需要将数据转换为树结构渲染展示,有时有需要将树结构数据展开铺平从而方便我们进行数据处理。
数据
有如下符合树结构的数据:
const list = [
{ name:'1'},
{ name:'1-1', parent:'1'},
{ name:'1-1-1', parent:'1-1'},
{ name:'1-2', parent:'1'},
{ name:'1-2-1', parent:'1-2'},
{ name:'1-3', parent:'1'},
{ name:'2', parent:null},
{ name:'2-1', parent:'2'},
{ name:'2-1-1', parent:'2-1'},
{ name:'2-2', parent:'2'},
{ name:'2-2-1', parent:'2-2'},
{ name:'2-1-1-1', parent:'2-1-1'},
]
转换为树结构
将如上的数据转换为树结构,具体代码如下:
function getTree(list){
if (!list || !list.length) {
return
}
const tree = [] // 存放结果
const map = {} // 存放对象映射关系
for (let item of list) {
//假设每个节点都有子节点,为每个节点添加 children 属性
item.children = []
// 使用对象的 name 属性作为 map 的 key 值,对应的对象为 value,建立对象映射关系
map[item.name] = { ...item }
if (item.parent) {
// 如果存在 parent 属性,说明它是某个节点的子节点
map[item.parent].children.push(map[item.name])
} else {
// 如果没有 parent 属性,说明它是根节点
tree.push(map[item.name])
}
}
return tree
}
// 使用
// 这里使用上面的 list 数据
const listToTree = getTree(list)
console.log(listToTree)
// 输出:
// [
// {
// "name": "1",
// "children": [
// {
// "name": "1-1",
// "parent": "1",
// "children": [
// {
// "name": "1-1-1",
// "parent": "1-1",
// "children": []
// }
// ]
// },
// {
// "name": "1-2",
// "parent": "1",
// "children": [
// {
// "name": "1-2-1",
// "parent": "1-2",
// "children": []
// }
// ]
// },
// {
// "name": "1-3",
// "parent": "1",
// "children": []
// }
// ]
// },
// {
// "name": "2",
// "parent": null,
// "children": [
// {
// "name": "2-1",
// "parent": "2",
// "children": [
// {
// "name": "2-1-1",
// "parent": "2-1",
// "children": [
// {
// "name": "2-1-1-1",
// "parent": "2-1-1",
// "children": []
// }
// ]
// }
// ]
// },
// {
// "name": "2-2",
// "parent": "2",
// "children": [
// {
// "name": "2-2-1",
// "parent": "2-2",
// "children": []
// }
// ]
// }
// ]
// }
// ]
树结构展开
将树结构的数据展开,具体代码如下:
//接收一个树结构的数据、子节点的key的名称、一个存放结果的数组作为参数
function expandTree(tree, childKey = 'children', list = []) {
if (!tree || !tree.length) {
return
}
//遍历树结构
for (let item of tree) {
list.push(item)
//如果子节点存在并且子节点包含其他节点
if (item[childKey] && item[childKey].length) {
//递归调用此方法
expandTree(item[childKey], childKey, list)
}
}
return list
}
// 使用
// 这里使用已经转换为树结构的数据 listToTree
const treeToList = expandTree(listToTree,'children')
console.log(treeToList)
//输出:
// [
// {name: '1', children: Array(3)},
// {name: '1-1', parent: '1', children: Array(1)},
// {name: '1-1-1', parent: '1-1', children: Array(0)},
// {name: '1-2', parent: '1', children: Array(1)},
// {name: '1-2-1', parent: '1-2', children: Array(0)}
// {name: '1-3', parent: '1', children: Array(0)},
// {name: '2', parent: null, children: Array(2)},
// {name: '2-1', parent: '2', children: Array(1)},
// {name: '2-1-1', parent: '2-1', children: Array(1)},
// {name: '2-1-1-1', parent: '2-1-1', children: Array(0)},
// {name: '2-2', parent: '2', children: Array(1)},
// {name: '2-2-1', parent: '2-2', children: Array(0)}
// ]