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

Angular中如何通过reduce函数返回符合要求的对象数组

解决方法

问题原因

  • 当前reduce的初始值为空对象{},累加逻辑也是直接给对象设置键值对,最终自然返回的是键值对结构的对象,而非目标数组
  • 另外注意this.activities$是异步流,你当前把this.aggregated的计算写在subscribe外面,会出现还没拿到接口返回的dati就先执行了计算的问题,导致结果为空

调整后代码

优先推荐下面的实现,时间复杂度更低:

this.activities$
  // 原代码里的pipe(map((e) => e.map((e) => e)))没有实际作用,可直接删除
  .subscribe((e) => {
    this.dati = e;
    // 计算逻辑移到subscribe内部,保证拿到的是接口返回的最新数据
    this.aggregated = Object.entries(
      this.dati.reduce((acc: Record<string, number>, activity) => {
        const projectName = `${activity.project?.customer.name} - ${activity.project?.name}`;
        // 第一步先按项目名分组统计工时,和你原有逻辑一致
        acc[projectName] = (acc[projectName] ?? 0) + activity.hours;
        return acc;
      }, {})
    // 第二步把统计完的键值对转换为目标数组结构
    ).map(([projectName, hours]) => ({
      project: projectName,
      hours: hours
    }));
  });

如果一定要纯用reduce一步完成,也可以用下面的写法:

this.aggregated = this.dati.reduce((acc: {project: string, hours: number}[], activity) => {
  const projectName = `${activity.project?.customer.name} - ${activity.project?.name}`;
  // 查找累加数组中是否已经存在当前项目
  const existProject = acc.find(item => item.project === projectName);
  if (existProject) {
    // 存在就叠加工时
    existProject.hours += activity.hours;
  } else {
    // 不存在就往数组新增一项
    acc.push({
      project: projectName,
      hours: activity.hours
    })
  }
  return acc;
}, []); // 初始值设置为空数组

说明

第一种实现对象查找的时间复杂度为O(1),整体复杂度仅为O(n),数据量较大时性能更好;第二种纯reduce实现每次需要遍历数组查找项目,复杂度为O(n²),仅适合数据量小的场景使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 05:09:02