JavaScript如何将扁平分类数组构建为向上嵌套的深度对象
问题原因
你的代码返回根节点的核心原因是递归返回逻辑写反了:
- 你当前的递归逻辑是从起始节点向上遍历到根节点,每次都返回父节点的递归结果,最终递归终止时会直接把根节点作为最终结果返回,完全丢弃了最开始的id=4的RAM节点引用
- 另外你的实现直接修改了原始
categories数组里的对象引用,会污染原始数据,产生意料之外的副作用
正确实现方案
推荐用不修改原始数据的写法,同时提前构建id映射表提升查询效率,不需要每次遍历数组找父节点:
const categories = [ {id: 1, name: "Main", parent: null}, {id: 2, name: "Computers", parent: 1}, {id: 3, name: "Components", parent: 2}, {id: 4, name: "RAM", parent: 3} ]; // 构建id到节点的映射,避免重复find遍历 const categoryMap = new Map(categories.map(item => [item.id, item])); /** * 从指定id的节点开始,向上构建嵌套父级结构 * @param {number} nodeId 起始节点id * @returns 挂载完整父级链的节点对象 */ const buildNestedChain = (nodeId) => { const originNode = categoryMap.get(nodeId); // 浅拷贝节点,避免修改原始数据 const currentNode = { ...originNode }; // 到达根节点,parent设为null后直接返回 if (originNode.parent === null) { currentNode.parent = null; return currentNode; } // 递归构建父级的嵌套链,挂载到当前节点的parent属性上 currentNode.parent = buildNestedChain(originNode.parent); return currentNode; }; // 从id=4的RAM节点开始构建 const result = buildNestedChain(4); console.log(result);
运行上述代码就能得到你期望的嵌套结构。
快速修复原有代码的方式
如果你不想大幅改动原有逻辑,只需要调整返回逻辑即可,注意这种方式会修改原始数组数据:
const recursiveBuild = (node) => { if (node.parent === null) { return; } const parent = categories.find((cat) => cat.id === node.parent); node.parent = parent; recursiveBuild(node.parent); }; const item4 = categories.find((cat) => cat.id === 4); recursiveBuild(item4); // 递归过程已经直接修改了item4的引用,此时item4就是目标结构 console.log(item4);
内容的提问来源于stack exchange,提问作者desh
相关产品推荐
相关产品推荐

