我有2个ArrayLists。一个是[[账户:价值,预算:价值]],另一个是[[账户:价值,cY预算:价值]]我希望以下列格式得到一个列表:[[账户:价值,预算:价值,cYBudget:value]]
数据的一个例子是:
budProp = [[ACCTCODE:6201,BUDGET:2500],[ACCTCODE:7999,BUDGET:1500]]
budCyExp = [[ACCTCODE:6201,cYBudget:1000],[ACCTCODE:7999,cYBudget:2000]]
我想结果:
[[ACCTCODE:6201,BUDGET:2500,cYBudget:1000],[ACCTCODE:7999,BUDGET:1500,cYBudget:2000]]
基本上我通过匹配ACCTCODE并确保每个列表包含ACCTCODE,BUDGET和cYBudget键/值对来“合并”两个列表。 Groovy有一些方法可以做到吗?
我正在使用Groovy 2.3.7
感谢。
答案 0 :(得分:0)
方法GroovyCollections#transpose()可以生成两个列表中的对列表:
groovy:000> [[1,2,3], [4,5,6]].transpose()
===> [[1, 4], [2, 5], [3, 6]]
如果您有两个具有相同顺序的相同帐户代码的列表,您可以使用转置方法将并行列表条目压缩成对映射,然后合并每对映射:
[budProp, budCyExp].transpose().collect { it[0] + it[1] }
以下是在groovysh中分解的步骤,以便您可以分别看到转置的结果:
groovy:000> budProp = [[ACCTCODE:6201, BUDGET:2500], [ACCTCODE:7999, BUDGET:1500]]
===> [[ACCTCODE:6201, BUDGET:2500], [ACCTCODE:7999, BUDGET:1500]]
groovy:000> budCyExp = [[ACCTCODE:6201,cYBudget:1000],[ACCTCODE:7999,cYBudget: 2000]]
===> [[ACCTCODE:6201, cYBudget:1000], [ACCTCODE:7999, cYBudget:2000]]
groovy:000> [budProp, budCyExp].transpose()
===> [[[ACCTCODE:6201, BUDGET:2500], [ACCTCODE:6201, cYBudget:1000]], [[ACCTCODE:7999, BUDGET:1500], [ACCTCODE:7999, cYBudget:2000]]]
groovy:000> _.collect { it[0] + it[1] }
===> [[ACCTCODE:6201, BUDGET:2500, cYBudget:1000], [ACCTCODE:7999, BUDGET:1500, cYBudget:2000]]
在现实生活中,我会犹豫不决,除非我100%确定并行列表完美排列(一个列表中的每个帐户代码都在另一个列表中表示),否则我会做类似的事情:
groovy:000> budMap = budProp.inject([:]) { m, e -> m[e['ACCTCODE']] = e['BUDGET']; m }
===> [6201:2500, 7999:1500]
groovy:000> cyMap = budCyExp.inject([:]) { m, e -> m[e['ACCTCODE']] = e['cYBudget']; m }
===> [6201:1000, 7999:2000]
groovy:000> (budMap.keySet() + cyMap.keySet()).collect { [ACCTCODE: it, BUDGET: budMap[it], cYBudget: cyMap[it] ] }
===> [[ACCTCODE:6201, BUDGET:2500, cYBudget:1000], [ACCTCODE:7999, BUDGET:1500,
cYBudget:2000]]
这不是简短但它处理的情况是一个列表中的帐户没有在另一个列表中表示。
答案 1 :(得分:0)
如果列表没有完美排列,那么使用Groovy Iterable.groupBy(Closure)方法会更合适:
def budProp = [[ACCTCODE:6201, BUDGET:2500], [ACCTCODE:7999, BUDGET:1500]]
def budCyExp = [[ACCTCODE:7999,cYBudget: 2000], [ACCTCODE:6201,cYBudget:1000]]
def budMaster = (budProp + budCyExp)
println budMaster
//[[ACCTCODE:6201, BUDGET:2500], [ACCTCODE:7999, BUDGET:1500], [ACCTCODE:7999, cYBudget:2000], [ACCTCODE:6201, cYBudget:1000]]
def budMappedAcct = budMaster.groupBy { it.ACCTCODE }
println budMappedAcct
// [6201:[[ACCTCODE:6201, BUDGET:2500], [ACCTCODE:6201, cYBudget:1000]], 7999:[[ACCTCODE:7999, BUDGET:1500], [ACCTCODE:7999, cYBudget:2000]]]
def budMapList = budMappedAcct.collect { code, mapList -> mapList.sum() }
println budMapList
// [[ACCTCODE:6201, BUDGET:2500, cYBudget:1000], [ACCTCODE:7999, BUDGET:1500, cYBudget:2000]]
这适用于无序和不匹配的列表,只要所有原始地图都有ACCTCODE
。如果需要,可以将该溶液浓缩成单衬里:
def budMapList = (budProp + budCyExp).groupBy { it.ACCTCODE }.collect { code, mapList -> mapList.sum() }