前言
做项目使常遇到需要将后台返回的数据,转换为树状结构给用户展现,例如:
这也是前端面试常考的算法题,一起来检测一下吧。
步骤
- 准备一个空的树对象。
- 遍历列表中的每个元素。
- 对于每个元素,根据该元素的父级ID找到其对应的父节点。
- 如果找到了父节点,则将该元素添加到父节点的子节点列表中。
- 如果没有找到父节点,则创建一个新的节点,并将该元素作为其子节点。
- 重复步骤 2~5,直到遍历完所有元素。
- 返回树对象。
代码示例
const list = [
{ id: 1, name: 'Node 1', parentId: null },
{ id: 2, name: 'Node 1-1', parentId: 1 },
{ id: 3, name: 'Node 1-2', parentId: 1 },
{ id: 4, name: 'Node 1-1-1', parentId: 2 },
{ id: 5, name: 'Node 2', parentId: null },
{ id: 6, name: 'Node 2-1', parentId: 5 },
]
function listToTree(list) {
const map = {} // 用于存储节点 id 与节点的映射关系
const tree = [] // 树的根节点
// 首次遍历,将节点 id 与节点进行映射
list.forEach(node => {
map[node.id] = { ...node, children: [] }
})
// 第二次遍历,构建树结构
list.forEach(node => {
if (node.parentId) {
// 如果存在父级节点,则将当前节点添加到父级节点的子节点列表中
map[node.parentId].children.push(map[node.id])
} else {
// 否则,将当前节点作为根节点
tree.push(map[node.id])
}
})
return tree
}
const tree = listToTree(list)
console.log(tree)
输出:
[
{
"id": 1,
"name": "Node 1",
"parentId": null,
"children": [
{
"id": 2,
"name": "Node 1-1",
"parentId": 1,
"children": [
{
"id": 4,
"name": "Node 1-1-1",
"parentId": 2,
"children": []
}
]
},
{
"id": 3,
"name": "Node 1-2",
"parentId": 1,
"children": []
}
]
},
{
"id": 5,
"name": "Node 2",
"parentId": null,
"children": [
{
"id": 6,
"name": "Node 2-1",
"parentId": 5,
"children": []
}
]
}
]
运用场景
1. 文件系统:将文件系统中的文件和文件夹组织为树状结构。
2. 组织架构:在企业中,可以使用树状结构来表示员工之间的关系,从而构建组织架构图。
3. 导航菜单:在网站或应用程序的导航菜单中,通常使用树状结构来表示不同的页面层级。
4. 评论回复:在社交媒体或论坛中,用户可以对评论进行回复,这种回复关系可以使用树状结构来组织和展示。
5. 分类目录:电商网站中的商品分类、博客中的文章分类等都可以使用树状结构进行组织和展示。