如何在JavaScript/ReactJS中实现类似SQL SUM+GROUP BY的数组分组求和
ReactJS中按ProjectType分组并对Amount、Hours求和
需求说明
需要处理如下对象数组frames,忽略EmployeeGroup字段,按ProjectType分组,分别对Amount和Hours求和:
原始数组:
const frames = [ { ProjectName: "Blue", EmployeeGroup: false, Amount: 50, Hours: 15, ProjectType: "Romeo", }, { ProjectName: "Red", EmployeeGroup: false, Amount: 20, Hours: 5, ProjectType: "Lima", }, { ProjectName: "Green", EmployeeGroup: true, Amount: 40, Hours: 10, ProjectType: "Lima", } ]
期望结果:
[ { ProjectType: "Lima", TotalAmount: 60, TotalHours: 15, }, { ProjectType: "Romeo", TotalAmount: 50, TotalHours: 15, } ]
你之前的代码只能单独获取某类的Amount求和值,下面提供两种更高效的实现方式:
方法一:使用reduce(全环境兼容)
reduce是JavaScript数组原生方法,兼容性最好,一次遍历即可完成分组与求和:
const frames = [ { ProjectName: "Blue", EmployeeGroup: false, Amount: 50, Hours: 15, ProjectType: "Romeo" }, { ProjectName: "Red", EmployeeGroup: false, Amount: 20, Hours: 5, ProjectType: "Lima" }, { ProjectName: "Green", EmployeeGroup: true, Amount: 40, Hours: 10, ProjectType: "Lima" } ]; const groupedResult = Object.values( frames.reduce((acc, currentItem) => { const projectType = currentItem.ProjectType; // 初始化分组结构(首次出现时) if (!acc[projectType]) { acc[projectType] = { ProjectType: projectType, TotalAmount: 0, TotalHours: 0 }; } // 累加对应数值 acc[projectType].TotalAmount += currentItem.Amount; acc[projectType].TotalHours += currentItem.Hours; return acc; }, {}) ); console.log(groupedResult);
逻辑说明
- 用
reduce遍历数组,以ProjectType作为临时对象acc的键; - 每个分组首次出现时,初始化包含目标字段的结构;
- 遍历每个元素时,对对应分组的
TotalAmount和TotalHours进行累加; - 最后用
Object.values()将临时对象转为数组,得到期望格式。
方法二:使用Array.group()(ES2024新特性)
如果你的运行环境支持ES2024(如现代浏览器、Node.js 21及以上版本),可以用更简洁的Array.group()方法:
const frames = [ { ProjectName: "Blue", EmployeeGroup: false, Amount: 50, Hours: 15, ProjectType: "Romeo" }, { ProjectName: "Red", EmployeeGroup: false, Amount: 20, Hours: 5, ProjectType: "Lima" }, { ProjectName: "Green", EmployeeGroup: true, Amount: 40, Hours: 10, ProjectType: "Lima" } ]; // 第一步:按ProjectType分组 const groupedByType = frames.group(item => item.ProjectType); // 第二步:对每个分组求和并转换格式 const groupedResult = Object.entries(groupedByType).map(([type, items]) => ({ ProjectType: type, TotalAmount: items.reduce((sum, item) => sum + item.Amount, 0), TotalHours: items.reduce((sum, item) => sum + item.Hours, 0) })); console.log(groupedResult);
逻辑说明
Array.group()直接按ProjectType将数组分组为对象,键为类型,值为对应元素数组;- 用
Object.entries()遍历分组对象,对每个分组的Amount和Hours分别求和,组装成目标结构。
内容的提问来源于stack exchange,提问作者MicBalla
相关产品推荐
相关产品推荐

