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

如何使用reduce创建含重复键的对象数组

数据结构转换问题解决

问题背景

现有如下结构的对象数组:

const data = [
  {
    "date": "2020-01-02",
    "run": [
      {"time": "1", "result": 100},
      {"time": "2", "result": 150},
      {"time": "3", "result": 92}
    ]
  },
  {
    "date": "2020-01-15",
    "run": [
      {"time": "1", "result": 90},
      {"time": "2", "result": 86},
      {"time": "3", "result": 133}
    ]
  },
  {
    "date": "2020-02-11",
    "run": [
      {"time": "1", "result": 45},
      {"time": "2", "result": 176},
      {"time": "3", "result": 108}
    ]
  },
]

需要转换为以下结构:

[
  {
    "time": 1,
    "2020-01-02": 100,
    "2020-01-15": 90,
    "2020-02-11": 45
  },
  {
    "time": 2,
    "2020-01-02": 150,
    "2020-01-15": 86,
    "2020-02-11": 176
  },
  {
    "time": 3,
    "2020-01-02": 92,
    "2020-01-15": 133,
    "2020-02-11": 108
  },
]

原代码问题分析

你之前的reduce代码存在几个关键问题:

  • 初始值设置错误,仅提取了第一个日期的第一个运行结果,未覆盖所有time项
  • reduce返回逻辑错误,最终得到单个混乱对象而非目标数组,且错误使用currIdx-1索引run项,导致取值错位
  • 未遍历每个run数组,无法完整收集每个time对应的多日期结果

正确实现方案

我们可以通过按time分组收集数据,再转换为目标数组的方式完成需求:

// 构建以time为键的映射对象,收集对应日期的结果
const timeMap = data.reduce((map, item) => {
  const currentDate = item.date;
  // 遍历当前日期下的所有运行记录
  item.run.forEach(run => {
    const timeNum = parseInt(run.time);
    // 初始化该time对应的对象(如果不存在)
    if (!map[timeNum]) {
      map[timeNum] = { time: timeNum };
    }
    // 为该time对象添加当前日期的结果
    map[timeNum][currentDate] = run.result;
  });
  return map;
}, {});

// 将映射对象的值转换为数组,得到最终结果
const finalResult = Object.values(timeMap);

console.log(finalResult);

代码说明

  1. 初始化空对象timeMap,用于存储每个time对应的所有日期结果
  2. 遍历原始数据中的每个日期项,再遍历该日期下的所有运行记录
  3. 将每个run的time转为数字作为键,为对应对象添加time字段和各日期的结果值
  4. 最后用Object.values()提取映射对象的所有值,转换为目标格式的数组

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 12:25:30