You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带条件的层级数据集遍历问题:无法收集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
    }
]

问题分析

  1. 递归结果未合并:调用traverse(d.children)时,函数返回的子节点处理结果没有被添加到当前的container中,导致子层级的节点丢失。
  2. 重复处理children:既递归调用traverse,又手动forEach遍历children,逻辑冗余且混乱,比如req="y"的子节点在手动遍历时被错误过滤,没被收集。
  3. 冗余判断: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 08:46:17