如何基于对象数组的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; }, {});
核心逻辑总结
- 按主名称分组:通过拆分id获取主名称,把同主名称的条目归为一组
- 区分allTime和today:纯主名称的条目直接作为
allTime,带后缀的条目求和后作为today
内容的提问来源于stack exchange,提问作者Muskan
相关产品推荐
相关产品推荐

