js list转tree
方法1:使用递归
这种方法适用于你知道数据中每个项的父级ID。你可以通过递归地查找每个项的父项,从而构建树形结构。
function listToTree(list, parentId = null) {
const tree = [];
let tempMap = {}; // 用于存储已处理的项,以便快速查找
// 首先,将列表转换为对象映射,并初始化tempMap
list.forEach(item => {
const { id, parentId: parentIdFromList, ...rest } = item;
tempMap[id] = { ...rest, children: [] };
});
// 再次遍历列表,构建树结构
list.forEach(item => {
const currentItem = tempMap[item.id];
const parentItem = tempMap[item.parentId];
if (parentItem) {
parentItem.children.push(currentItem);
} else if (item.parentId === parentId) { // 顶层节点
tree.push(currentItem);
}
});
return tree;
}
方法2:使用循环和查找
function listToTree(list) {
const tree = [];
const itemsMap = {}; // 用于存储所有项的映射,方便快速查找
const rootItems = []; // 存储顶层项
// 创建项的映射并找出所有顶层项(即那些没有在其他项中作为parentId的项)
list.forEach(item => {
itemsMap[item.id] = { ...item, children: [] }; // 初始化children数组
if (!list.some(i => i.parentId === item.id)) { // 如果没有其他项的parentId等于当前项的id,则为顶层项
rootItems.push(item.id);
}
});
// 构建树结构
rootItems.forEach(rootId => {
let node = itemsMap[rootId];
buildTree(node, itemsMap); // 从顶层节点开始构建树
tree.push(node); // 添加到最终树结果中
});
return tree;
}
function buildTree(node, itemsMap) {
const children = list.filter(item => item.parentId === node.id); // 找出当前节点的所有子节点
children.forEach(child => {
const childNode = itemsMap[child.id];
node.children.push(childNode); // 添加到当前节点的children数组中
buildTree(childNode, itemsMap); // 递归构建子树
});
}
择善人而交,择善书而读,择善言而听,择善行而从。