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

JavaScript循环创建对象数组异常:预期生成2个对象却生成8个的解决方案咨询

解决动态数组按fila分组整合属性的问题

你的问题核心在于遍历每个元素时都创建了新对象并推入数组,导致每个对象只填充了当前元素对应的属性,最终生成了和原数组长度相同的对象数组。我们需要先按fila值分组,再把同组的属性整合到一个对象里,而且这个方案要能动态适配任意数量的fila值,不需要硬编码判断。

最优解决方案:使用reduce分组构建对象

这里用reduce来高效完成分组和属性赋值,代码简洁且动态适配:

const columnas = [
 { nombre: 'ORDEN', fila: 1, campoDb: 'NUMBER1' },
 { nombre: 'CONTRAPARTIDA', fila: 1, campoDb: 'STRING1' },
 { nombre: 'NOMBRE', fila: 1, campoDb: 'STRING2' },
 { nombre: 'VALOR ENV.', fila: 1, campoDb: 'NUMBER2' },
 { nombre: 'ORDEN', fila: 2, campoDb: 'NUMBER1' },
 { nombre: 'CONTRAPARTIDA', fila: 2, campoDb: 'STRING1' },
 { nombre: 'NOMBRE', fila: 2, campoDb: 'STRING2' },
 { nombre: 'VALOR ENV.', fila: 2, campoDb: 'NUMBER2' },
];

// 按fila分组,同时构建每个组的完整对象结构
const groupedByFila = columnas.reduce((acc, item) => {
  // 若当前fila未初始化,先创建带默认null的基础对象
  if (!acc[item.fila]) {
    acc[item.fila] = {
      string1: null,
      string2: null,
      string3: null,
      number1: null,
      number2: null,
      number3: null
    };
  }
  // 将当前item的nombre赋值到对应的属性(注意大小写转换)
  acc[item.fila][item.campoDb.toLowerCase()] = item.nombre;
  return acc;
}, {});

// 将分组对象转换为数组,得到最终结果
const arrayFinal = Object.values(groupedByFila);

console.log(arrayFinal);

代码逻辑解释

  1. 分组初始化:遍历columnas时,遇到新的fila值就创建一个包含所有目标属性(默认值为null)的对象,确保结构完整性。
  2. 属性赋值:根据每个元素的campoDb值,把nombre对应赋值到分组对象的属性中(因为campoDb是大写,目标属性是小写,所以用toLowerCase()统一格式)。
  3. 转换为数组:用Object.values()把分组对象的所有值提取出来,得到按fila分组的完整对象数组,不管有多少个不同的fila值都能适配。

替代方案:使用普通for循环

如果你更习惯用普通循环,也可以实现相同效果:

const columnas = [
 { nombre: 'ORDEN', fila: 1, campoDb: 'NUMBER1' },
 { nombre: 'CONTRAPARTIDA', fila: 1, campoDb: 'STRING1' },
 { nombre: 'NOMBRE', fila: 1, campoDb: 'STRING2' },
 { nombre: 'VALOR ENV.', fila: 1, campoDb: 'NUMBER2' },
 { nombre: 'ORDEN', fila: 2, campoDb: 'NUMBER1' },
 { nombre: 'CONTRAPARTIDA', fila: 2, campoDb: 'STRING1' },
 { nombre: 'NOMBRE', fila: 2, campoDb: 'STRING2' },
 { nombre: 'VALOR ENV.', fila: 2, campoDb: 'NUMBER2' },
];

let groupedByFila = {};
for (const item of columnas) {
  if (!groupedByFila[item.fila]) {
    groupedByFila[item.fila] = {
      string1: null,
      string2: null,
      string3: null,
      number1: null,
      number2: null,
      number3: null
    };
  }
  groupedByFila[item.fila][item.campoDb.toLowerCase()] = item.nombre;
}

const arrayFinal = Object.values(groupedByFila);
console.log(arrayFinal);

为什么你的原代码不符合预期?

原代码中,你遍历columnas的每个元素时,每次都创建一个新对象并推入arrayFinal,导致每个对象只有当前元素对应的属性被赋值(其他都是null),8个元素就生成了8个不完整的对象。而我们需要的是把同fila的所有属性合并到一个对象里,所以必须先分组再构建对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 05:57:32