扁平化对象转树形结构:自定义函数问题排查求助
扁平化数组转树形结构问题排查与修复
问题场景
输入结构(扁平化对象)
interface FlatObject { id: string; parentId: string; }
期望输出结构(嵌套树形对象)
interface NestedObject { id: string; parentId: string; children: NestedObject[]; }
原函数核心问题
编写的list_to_tree函数无法生成预期树形结构,错误点如下:
- 重复添加父节点到root:遍历节点时,每次处理子节点都会将父节点追加到root的children数组,导致root的children出现大量重复节点,结构混乱
- 遍历范围冗余:遍历
Object.values(tree)会包含root节点,虽不触发逻辑,但多余且易引发问题 - 未处理顶级节点:未考虑parentId不存在的顶级节点归属逻辑
原函数代码:
function list_to_tree(arr: any[]) { const tree = { root: { id: "root", children: [] } } arr.forEach(item => { tree[item.id] = { ...item, children: [] } }) Object.values(tree).forEach(item => { if (item.parentId) { tree[item.parentId].children.push(item) const i = tree[item.parentId] tree.root.children.push(i) } }) return tree.root }
修复后的代码
function list_to_tree(arr: any[]) { const nodeMap = { root: { id: "root", children: [] } }; // 初始化所有节点到映射表,创建空children数组 arr.forEach(item => { nodeMap[item.id] = { ...item, children: [] }; }); // 构建树形层级关系 arr.forEach(item => { const currentNode = nodeMap[item.id]; const parentNode = nodeMap[item.parentId]; if (parentNode) { // 父节点存在,将当前节点加入父节点的children parentNode.children.push(currentNode); } else { // 父节点不存在,当前节点为顶级节点,加入root的children nodeMap.root.children.push(currentNode); } }); return nodeMap.root; }
修复说明
- 仅遍历输入数组中的业务节点,避免处理root节点
- 逻辑清晰:每个节点仅被添加到其父节点的children数组,顶级节点直接加入root的children,无重复添加
- 兼容parentId不存在的顶级节点场景
内容的提问来源于stack exchange,提问作者Stefano Brandi
相关产品推荐
相关产品推荐

