带条件的层级数据集遍历问题:无法收集req='y'节点转换结果
层级数据集遍历与数据转换问题解决
问题背景
需要处理一个层级嵌套的数据集,遍历所有节点层级,根据req字段的不同值转换数据,并把转换后的元素存入数组。但现有代码无法正确收集req="y"节点的转换结果,原始代码如下:
const data = [ { name: "f1",req: "n",val: 0, children: [ { name: "l1", req: "n", val: 1 }, { name: "s1", req: "y", val: 2 }, { name: "q1", req: "y", val: 3, children: [{ name: "i1" }, { name: "l1" }] } ] }, { name: "d1", req: "n", val: 4, children: [{ name: "s1" }] } ]; function traverse(data) { let container = []; data.forEach((d, i) => { if (d.req === "n") { container.push({ name: d.name, val: d.val * 100 }); if (d.children) { traverse(d.children); d.children.forEach((d) => { if (d.req === "n") { container.push({ name: d.name, val: d.val * 100 }); } }); } } else { if (d.req === "y") { container.push({ name: d.name, val: d.val * -100 }); if (d.children) { traverse(d.children); d.children.forEach((d) => { if (d.req === "y") { container.push({ name: d.name, val: d.val * -100 }); } }); } } } }); return container; } console.log( traverse(data));
期望输出:
[{ "name": "f1", "val": 0 }, { "name": "l1", "val": 100 }, { "name": "d1", "val": 400 }, { "name": "s1", "val": -200 }, { "name": "q1", "val": -300 } ]
问题分析
- 递归结果未合并:调用
traverse(d.children)时,函数返回的子节点处理结果没有被添加到当前的container中,导致子层级的节点丢失。 - 重复处理children:既递归调用
traverse,又手动forEach遍历children,逻辑冗余且混乱,比如req="y"的子节点在手动遍历时被错误过滤,没被收集。 - 冗余判断:
else分支里的if (d.req === "y")完全多余,因为else已经是d.req !== "n"的情况,直接处理即可。
修复后的代码
重构遍历逻辑,让递归函数返回当前层级及所有子层级的处理结果,通过concat合并到数组中:
const data = [ { name: "f1",req: "n",val: 0, children: [ { name: "l1", req: "n", val: 1 }, { name: "s1", req: "y", val: 2 }, { name: "q1", req: "y", val: 3, children: [{ name: "i1" }, { name: "l1" }] } ] }, { name: "d1", req: "n", val: 4, children: [{ name: "s1" }] } ]; function traverse(data) { let container = []; data.forEach(d => { // 处理当前节点 if (d.req === "n") { container.push({ name: d.name, val: d.val * 100 }); } else if (d.req === "y") { container.push({ name: d.name, val: d.val * -100 }); } // 递归处理子节点,并合并结果 if (d.children) { container = container.concat(traverse(d.children)); } }); return container; } console.log(traverse(data));
结果验证
运行修复后的代码,输出完全符合预期:
[ { "name": "f1", "val": 0 }, { "name": "l1", "val": 100 }, { "name": "s1", "val": -200 }, { "name": "q1", "val": -300 }, { "name": "d1", "val": 400 } ]
注:输出顺序与期望略有不同,但所有目标节点均已正确收集,若需要严格顺序可后续调整遍历逻辑。
内容的提问来源于stack exchange,提问作者smpa01
相关产品推荐
相关产品推荐

