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

JavaScript数组对象转换异常:结果重复最后索引数据

数组对象转换时出现重复数据的问题分析与解决

问题描述

将数组对象转换为指定格式时,输出结构符合预期,但新数组的每个索引位置都被最后一个索引的对象覆盖,所有元素都是重复的最后一组数据。

输入数据

let data = [
  {
    0: {
      value1: true,
      value2: false,
      isSelected: false,
    },
    1: {
      value1: true,
      value2: true,
      isSelected: true,
    },
    2: {
      value1: false,
      value2: false,
      isSelected: false,
    },
    3: {
      value1: false,
      value2: false,
      isSelected: false,
    },
    4: {
      value1: true,
      value2: true,
      isSelected: true,
    },
    Stage: 'A',
  },
  {
    0: {
      value1: false,
      value2: false,
      isSelected: false,
    },
    1: {
      value1: true,
      value2: true,
      isSelected: true,
    },
    2: {
      value1: false,
      value2: false,
      isSelected: false,
    },
    3: {
      value1: false,
      value2: false,
      isSelected: false,
    },
    4: {
      value1: true,
      value2: true,
      isSelected: true,
    },
    Stage: 'B',
  },
  {
    0: {
      value1: false,
      value2: false,
      isSelected: false,
    },
    1: {
      value1: true,
      value2: true,
      isSelected: true,
    },
    2: {
      value1: false,
      value2: false,
      isSelected: false,
    },
    3: {
      value1: false,
      value2: false,
      isSelected: false,
    },
    4: {
      value1: true,
      value2: true,
      isSelected: true,
    },
    Stage: 'C',
  },
];

预期输出

// 预期输出数据
[
  {
    Stage: [
      {
        value1: true,
        value2: false,
        isSelected: false,
      },
      {
        value1: true,
        value2: true,
        isSelected: true,
      },
      {
        value1: false,
        value2: false,
        isSelected: false,
      },
      {
        value1: false,
        value2: false,
        isSelected: false,
      },
      {
        value1: true,
        value2: true,
        isSelected: true,
      },
    ],
  },
  {
    Stage: [
      {
        value1: false,
        value2: false,
        isSelected: false,
      },
      {
        value1: true,
        value2: true,
        isSelected: true,
      },
      {
        value1: false,
        value2: false,
        isSelected: false,
      },
      {
        value1: false,
        value2: false,
        isSelected: false,
      },
      {
        value1: true,
        value2: true,
        isSelected: true,
      },
    ],
  },
  {
    Stage: [
      {
        value1: false,
        value2: false,
        isSelected: false,
      },
      {
        value1: true,
        value2: true,
        isSelected: true,
      },
      {
        value1: false,
        value2: false,
        isSelected: false,
      },
      {
        value1: false,
        value2: false,
        isSelected: false,
      },
      {
        value1: true,
        value2: true,
        isSelected: true,
      },
    ],
  },
];

尝试的代码

stagesBackTransform = (data) => {
  let newArr = new Array(data.length).fill({ Stage: new Array(16) });

  data.forEach((stage, stageIdx) => {
    Object.entries(stage).forEach((item, idx) => {
      if (item[0] !== 'Stage') {
        // newArr[stageIdx].Stage[item[0]] = item[1];
        newArr[stageIdx].Stage[idx] = item[1];
      }
    });
  });
  console.log('new:', newArr);
  return newArr;
};

运行代码片段

let data = [
  {
    0: { value1: true, value2: false, isSelected: false },
    1: { value1: true, value2: true, isSelected: true },
    2: { value1: false, value2: false, isSelected: false },
    3: { value1: false, value2: false, isSelected: false },
    4: { value1: true, value2: true, isSelected: true },
    Stage: 'A',
  },
  {
    0: { value1: false, value2: false, isSelected: false },
    1: { value1: true, value2: true, isSelected: true },
    2: { value1: false, value2: false, isSelected: false },
    3: { value1: false, value2: false, isSelected: false },
    4: { value1: true, value2: true, isSelected: true },
    Stage: 'B',
  },
  {
    0: { value1: false, value2: false, isSelected: false },
    1: { value1: true, value2: true, isSelected: true },
    2: { value1: false, value2: false, isSelected: false },
    3: { value1: false, value2: false, isSelected: false },
    4: { value1: true, value2: true, isSelected: true },
    Stage: 'C',
  },
];

stagesBackTransform = (data) => {
  let newArr = new Array(data.length).fill({ Stage: new Array(16) });

  data.forEach((stage, stageIdx) => {
    Object.entries(stage).forEach((item, idx) => {
      if (item[0] !== 'Stage') {
        // newArr[stageIdx].Stage[item[0]] = item[1];
        newArr[stageIdx].Stage[idx] = item[1];
      }
    });
  });
  console.log('new:', newArr);
  return newArr;
};

const result = stagesBackTransform(data);

console.log(result);

错误原因

问题出在创建newArr的这一行:

let newArr = new Array(data.length).fill({ Stage: new Array(16) });

Array.fill()方法会将同一个对象引用填充到数组的所有位置。也就是说,newArr里的每一个元素都指向同一个{ Stage: [...] }对象。后续循环中修改任意索引的Stage数组时,都是在修改这个共享的对象,最终所有元素都会显示最后一次修改的结果,导致数据重复。

修正后的代码

改用Array.from()创建独立的对象,确保每个数组元素都是全新的对象引用:

stagesBackTransform = (data) => {
  // 用Array.from创建每个独立的对象,避免引用共享
  let newArr = Array.from({ length: data.length }, () => ({ Stage: new Array(16) }));

  data.forEach((stage, stageIdx) => {
    // 先过滤掉'Stage'键,再按数字排序确保顺序正确
    Object.keys(stage)
      .filter(key => key !== 'Stage')
      .sort((a, b) => Number(a) - Number(b))
      .forEach((key, idx) => {
        newArr[stageIdx].Stage[idx] = stage[key];
      });
  });
  console.log('new:', newArr);
  return newArr;
};

另外,这里增加了对数字键的排序处理,避免Object.keys()返回的键顺序不稳定导致的赋值错误,让转换结果更可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 04:20:27