Groovy实现相同year的对象amount值求和:代码问题与修正需求
问题:按年份汇总对象数组的金额值
原始数据
我有两组对象数组:
[ { id: '1109', year: 2022, amount: 558270 }, { id: '1109', year: 2022, amount: 22842680 }, { id: '1109', year: 2021, amount: 32342 }, { id: '1109', year: 2020, amount: 323111 } ], [ { id: '197', year: 2019, amount: 9000 }, { id: '197', year: 2023, amount: 3000 }, { id: '197', year: 2019, amount: 2000 }, { id: '197', year: 2020, amount: 1000 } ]
需求
将每组数组中相同year的对象的amount值求和,生成新数组。
当前代码(存在问题)
我写了以下Groovy代码,但输出不符合预期:
def newVal = [:] def arr = [] for(int ii=0 ; ii< arr.size(); ii++){ for(int jj=1 ; jj < arr.size(); jj++){ if(arr[ii].year == arr[jj].year){ newVal.put("id", arr[i].id) newVal.put("year", arr[ii].year) newVal.put("amount", arr[ii].amount + arr[jj].amount) arr.add(newVal) } } }
当前错误输出
运行后得到的错误结果:
[ { id: '1109', year: 2022, amount: 23400950 }, { id: '1109', year: 2022, amount: 45685360 }, { id: '1109', year: 2021, amount: 64684 }, { id: '1109', year: 2020, amount: 646222 } ] [ { id: '197', year: 2019, amount: 11000 }, { id: '197', year: 2023, amount: 6000 }, { id: '197', year: 2019, amount: 4000 }, { id: '197', year: 2020, amount: 2000 } ]
期望正确输出
我需要的正确结果是:
[ { id: '1109', year: 2022, amount: 23400950 }, { id: '1109', year: 2021, amount: 32342 }, { id: '1109', year: 2020, amount: 323111 } ], [ { id: '197', year: 2019, amount: 11000 }, { id: '197', year: 2023, amount: 3000 }, { id: '197', year: 2020, amount: 1000 } ]
修正后的代码
问题分析
之前的代码存在多个问题:
- 初始化
arr为空数组,循环根本不会执行(你需要将输入数组赋值给arr) - 嵌套循环重复比较,导致同一年份被多次计算,还修改了原数组产生重复条目
- 使用同一个
newValMap,每次修改会覆盖之前的值,且数组中存储的是引用,导致后续修改影响已有条目 - 变量名错误:
arr[i].id中的i应为ii - 未处理单个对象的年份,错误地进行自加计算
正确实现
利用Groovy的集合操作可以简洁完成需求,代码如下:
// 定义两组原始数据 def group1 = [ [id: '1109', year: 2022, amount: 558270], [id: '1109', year: 2022, amount: 22842680], [id: '1109', year: 2021, amount: 32342], [id: '1109', year: 2020, amount: 323111] ] def group2 = [ [id: '197', year: 2019, amount: 9000], [id: '197', year: 2023, amount: 3000], [id: '197', year: 2019, amount: 2000], [id: '197', year: 2020, amount: 1000] ] // 封装汇总逻辑为通用方法 def summarizeByYear(List data) { // 按id和year分组,确保同一id下的同一年份归为一组 data.groupBy { [it.id, it.year] }.collect { key, items -> [ id: key[0], year: key[1], // 对分组内的amount求和 amount: items.sum { it.amount } ] } } // 生成结果 def result1 = summarizeByYear(group1) def result2 = summarizeByYear(group2) // 打印输出 println(result1) println(result2)
代码说明
groupBy { [it.id, it.year] }:将数组按id和year的组合分组,确保同一id下的同一年份不会被拆分items.sum { it.amount }:对每组内的所有对象的amount值求和- 最终
collect将分组后的结果转换为需要的对象结构,每个年份只保留一条汇总记录
内容的提问来源于stack exchange,提问作者Mohamed Khalifa
相关产品推荐
相关产品推荐

