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

JavaScript遍历对象数组提取嵌套数组数据的问题排查

问题根源

你的代码有3个核心错误:

  • 对象引用复用:你在外层父级循环里只创建了一次obj,内层遍历嵌套components数组时,反复修改的是同一个对象的内存引用,push进结果数组的所有项都指向这同一个对象,最终所有项都会被最后一次循环的赋值覆盖,出现重复值。
  • id生成逻辑错误:你用父级数组的索引i+1作为id,但每个父项对应多个components子项,会导致id重复,无法匹配期望结果里从1到4连续自增的id。
  • 字段取值不兼容:示例数据里第二个父项的用户id字段是uKeyId而非uId,第二个组件的配件字段是part而非partNumber,统一按固定字段取值会出现undefined。
修复后的代码

基础for循环实现(和你原有写法逻辑最贴近)

const getNewDataSet = (d) => {
  const newArr = [];
  // 全局自增id计数器
  let currentId = 1;

  for (let i = 0; i < d.length; i++) {
    const parent = d[i];
    // 兼容父级两种id字段,匹配期望结果里的uId值
    const uId = parent.uId ?? parent.uKeyId ?? (i + 1);

    for (let k = 0; k < parent.components.length; k++) {
      const comp = parent.components[k];
      // 每个子项单独创建新对象,彻底避免引用复用问题
      const item = {
        id: currentId++,
        uId: uId,
        location: parent.location,
        modelId: comp.modelId,
        description: comp.description
      };
      // 兼容组件两种配件字段
      if (comp.partNumber) item.partNumber = comp.partNumber;
      if (comp.part) item.part = comp.part;

      newArr.push(item);
    }
  }

  return newArr;
};

// 执行测试
console.log(getNewDataSet(data));

运行后输出的结果和你给出的期望结果完全一致。

简洁写法(可选)

如果习惯用数组内置方法,可以用flatMap简化实现:

const getNewDataSet = (d) => {
  let currentId = 1;
  return d.flatMap((parent, idx) => {
    const uId = parent.uId ?? parent.uKeyId ?? (idx + 1);
    return parent.components.map(comp => {
      const baseItem = {
        id: currentId++,
        uId,
        location: parent.location,
        modelId: comp.modelId,
        description: comp.description
      };
      return comp.partNumber 
        ? {...baseItem, partNumber: comp.partNumber}
        : {...baseItem, part: comp.part};
    })
  })
};

内容的提问来源于stack exchange,提问作者subparmelon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 17:54:30