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

如何基于对象数组的ID后缀分组,区分计算allTime与today的汇总值?

如何按ID分组并汇总allTime与today数据?

嘿,我来帮你搞定这个问题!你的思路方向是对的,但问题出在分组的key选得不对,还有后续的处理逻辑没跟上。咱们一步步来修正:

先分析你的代码问题

你用_.groupBy(resultSet, value => value.id)是按完整的id分组,这样robin、robin_1、robin_2会分成三个独立的组,而不是归到同一个robin组下,这就和你的需求不符啦。而且groupBy返回的是对象,直接用map也没法直接构建出你要的嵌套结构。

正确的Lodash实现方案

我们需要先按主名称(去掉_数字后缀的部分)分组,再区分allTime和today的数据。这里用_.transform会更灵活,它可以边遍历数组边构建目标对象:

const resultSet = [ 
  { id: 'robin', savings: 5500, cost: 1200 }, 
  { id: 'robin_1', savings: 50, cost: 100 }, 
  { id: 'robin_2', savings: 50, cost: 150 }, 
  { id: 'steve', savings: 100, cost: 1000 }, 
  { id: 'steve_1', savings: 50, cost: 550 }, 
  { id: 'steve_2', savings: 50, cost: 150 } 
];

const output = _.transform(resultSet, (acc, item) => {
  // 提取主名称:分割id,取第一个部分
  const mainId = item.id.split('_')[0];
  
  // 初始化当前主名称的结构(如果还没创建)
  if (!acc[mainId]) {
    acc[mainId] = {
      allTime: { savings: 0, cost: 0 },
      today: { savings: 0, cost: 0 }
    };
  }
  
  // 判断当前条目属于allTime还是today
  if (item.id === mainId) {
    // 纯主名称,直接赋值给allTime(移除不需要的id字段)
    acc[mainId].allTime = { savings: item.savings, cost: item.cost };
  } else {
    // 带后缀,将数值累加到today
    acc[mainId].today.savings += item.savings;
    acc[mainId].today.cost += item.cost;
  }
}, {});

console.log(output);

另一种基于groupBy的实现

如果你更想用groupBy先分组再处理,也可以这么写:

const grouped = _.groupBy(resultSet, item => item.id.split('_')[0]);

const output = _.mapValues(grouped, items => {
  // 找到allTime条目:id不带下划线的那个
  const allTimeItem = items.find(item => !item.id.includes('_'));
  const allTime = { savings: allTimeItem.savings, cost: allTimeItem.cost };
  
  // 计算today的总和:过滤掉allTime条目后求和
  const todayItems = items.filter(item => item.id !== allTimeItem.id);
  const today = {
    savings: _.sumBy(todayItems, 'savings'),
    cost: _.sumBy(todayItems, 'cost')
  };
  
  return { allTime, today };
});

原生JS实现(无需Lodash)

如果项目里不想依赖Lodash,用reduce也能轻松实现:

const resultSet = [ /* 你的数组 */ ];

const output = resultSet.reduce((acc, item) => {
  const mainId = item.id.split('_')[0];
  
  if (!acc[mainId]) {
    acc[mainId] = {
      allTime: { savings: 0, cost: 0 },
      today: { savings: 0, cost: 0 }
    };
  }
  
  if (item.id === mainId) {
    acc[mainId].allTime.savings = item.savings;
    acc[mainId].allTime.cost = item.cost;
  } else {
    acc[mainId].today.savings += item.savings;
    acc[mainId].today.cost += item.cost;
  }
  
  return acc;
}, {});

核心逻辑总结

  1. 按主名称分组:通过拆分id获取主名称,把同主名称的条目归为一组
  2. 区分allTime和today:纯主名称的条目直接作为allTime,带后缀的条目求和后作为today

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 04:37:39