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

JavaScript:合并同一数组内多对象并重构数据结构

嘿,这个需求其实挺常见的,用JavaScript的数组方法就能轻松实现,给你几个实用的方案:

解决方案

方法一:map + reduce(简洁优雅)

这是最常用的写法,利用数组的高阶方法快速完成合并求和:

var data = [ 
  [{ jan: 10, feb: 20, mar: 30, type: "one" }, { jan: 20, feb: 10, mar: 40, type: "one" }], 
  [ { jan: 10, feb: 20, mar: 30, type: "two" }, { jan: 20, feb: 10, mar: 40, type: "two" }] 
];

const mergedData = data.map(group => {
  return group.reduce((acc, curr) => {
    // 累加月份字段的值
    acc.jan += curr.jan;
    acc.feb += curr.feb;
    acc.mar += curr.mar;
    // 保留type(同组内type一致,随便取哪个都没问题)
    acc.type = curr.type;
    return acc;
  }, { jan: 0, feb: 0, mar: 0, type: '' }); // 初始化累加对象
});

console.log(mergedData);

代码解释:

  • 外层map遍历原数组的每个子数组(也就是同一type的对象分组)
  • 每个子数组用reduce做累加:初始值是一个预设好结构的空对象,字段初始值为0
  • 每次迭代时,把当前对象的月份字段值加到累加对象的对应字段上,同时同步type字段
  • 最终map会把每个分组的合并结果收集成新数组,就是你要的结构

方法二:嵌套循环(直观易懂)

如果刚接触JavaScript,觉得高阶方法有点绕,可以用更直观的嵌套循环实现:

var data = [ 
  [{ jan: 10, feb: 20, mar: 30, type: "one" }, { jan: 20, feb: 10, mar: 40, type: "one" }], 
  [ { jan: 10, feb: 20, mar: 30, type: "two" }, { jan: 20, feb: 10, mar: 40, type: "two" }] 
];

const mergedData = [];

// 遍历每个分组
for (const group of data) {
  // 初始化合并对象,用分组第一个元素的type
  const mergedItem = { jan: 0, feb: 0, mar: 0, type: group[0].type };
  // 遍历分组里的每个对象,累加字段值
  for (const item of group) {
    mergedItem.jan += item.jan;
    mergedItem.feb += item.feb;
    mergedItem.mar += item.mar;
  }
  // 把合并好的对象加入结果数组
  mergedData.push(mergedItem);
}

console.log(mergedData);

代码解释:

  • 先创建空数组存储最终结果
  • 外层循环遍历每个type的分组,先初始化一个合并对象,预设字段初始值为0,type直接取分组第一个元素的(因为同组type都一样)
  • 内层循环遍历分组里的每个对象,把月份字段的值逐个累加到合并对象里
  • 最后把合并好的对象推入结果数组即可

进阶优化:动态处理字段(适配未来扩展)

如果以后要加新的月份字段(比如apr、may),不想每次手动修改代码,可以用动态遍历的方式:

var data = [ 
  [{ jan: 10, feb: 20, mar: 30, type: "one" }, { jan: 20, feb: 10, mar: 40, type: "one" }], 
  [ { jan: 10, feb: 20, mar: 30, type: "two" }, { jan: 20, feb: 10, mar: 40, type: "two" }] 
];

const mergedData = data.map(group => {
  return group.reduce((acc, curr) => {
    // 遍历当前对象的所有键
    for (const key in curr) {
      if (key === 'type') {
        // type字段直接赋值
        acc[key] = curr[key];
      } else {
        // 数字字段自动累加,兼容新增字段
        acc[key] = (acc[key] || 0) + curr[key];
      }
    }
    return acc;
  }, {}); // 初始化为空对象,动态生成字段
});

console.log(mergedData);

这种写法不管以后加多少数字类型的字段,都不需要修改累加逻辑,灵活性更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:07:05