作者: 云峰 github: github.com/ihtml5
一、背景
数组转树是指通过一个数组结构生成一个树形结构。日常我们看到的菜单就是这类数据结构的应用,后台下发的数据一般是拍平后的数组,通过数组中的parentId和id之间的关系来建立树形结构。
二、数据示例
const nodes = [
{ id: 3, name: "节点C", parentId: 1 },
{ id: 6, name: "节点F", parentId: 3 },
{ id: 0, name: "root", parentId: null },
{ id: 1, name: "节点A", parentId: 0 },
{ id: 8, name: "节点H", parentId: 4 },
{ id: 4, name: "节点D", parentId: 1 },
{ id: 2, name: "节点B", parentId: 0 },
{ id: 5, name: "节点E", parentId: 2 },
{ id: 7, name: "节点G", parentId: 2 },
{ id: 9, name: "节点I", parentId: 5 }
];
三、递归法
思路
从根节点出发,逐层进行递归 root -> 1 -> 2
const arrayToTree = (nodes, parentId) => {
const list = nodes.filter(node => node.parentId === parentId);
if (list.length === 0) {
return [];
}
return list.map(item => ({
...item,
children: arrayToTree(nodes, item.id),
}));
};
四、对象引用
const convert = (nodes) => {
const tree = [];
let map = {};
nodes.forEach(node => {
if (!Array.isArray(node.children)) {
node.children = [];
}
map[node.id] = node;
});
nodes.forEach(node => {
const parent = map[node.parentId] || null;
if (parent !== null) {
parent.children.push(node);
} else {
tree.push(node);
}
});
map = null;
return tree;
};