Groovy 将新的键值对添加到arraylist

Groovy 将新的键值对添加到arraylist,groovy,Groovy,我有两个数组列表。一个是[[Account:value,Budget:value]],另一个是[[Account:value,cYBudget:value]]我想以以下格式的列表结束:[[Account:value,Budget:value,cYBudget:value]] 数据的一个例子是: budProp=[[ACCTCODE:6201,预算:2500],[ACCTCODE:7999,预算:1500]] budCyExp=[[ACCTCODE:6201,cYBudget:1000],[ACC

我有两个数组列表。一个是[[Account:value,Budget:value]],另一个是[[Account:value,cYBudget:value]]我想以以下格式的列表结束:[[Account:value,Budget:value,cYBudget:value]]

数据的一个例子是:

budProp=[[ACCTCODE:6201,预算:2500],[ACCTCODE:7999,预算:1500]]

budCyExp=[[ACCTCODE:6201,cYBudget:1000],[ACCTCODE:7999,cYBudget:2000]]

我想了解以下方面的结果:

[[ACCTCODE:6201,预算:2500,cYBudget:1000],[ACCTCODE:7999,预算:1500,cYBudget:2000]]

基本上,我通过匹配ACCTCODE并确保每个列表包含ACCTCODE、BUDGET和cYBudget键/值对来“合并”这两个列表。Groovy有什么方法可以做到这一点吗

我正在使用Groovy 2.3.7

谢谢。

该方法可以从两个列表中生成一个对列表:

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]]
这并不短,但它可以处理一个列表中的帐户在另一个列表中不表示的情况。

该方法可以从两个列表中生成一个对列表:

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]]

这并不短,但它可以处理一个列表中的帐户在另一个列表中没有表示的情况。

如果列表没有完全对齐,则更适合使用Groovy方法:

这也适用于无序和不匹配的列表,只要所有原始地图都有
ACCTCODE
。如果需要,该溶液可浓缩成一层:

def budMapList = (budProp + budCyExp).groupBy { it.ACCTCODE }.collect { code, mapList -> mapList.sum() }

如果列表没有完全对齐,则更适合使用Groovy方法:

这也适用于无序和不匹配的列表,只要所有原始地图都有
ACCTCODE
。如果需要,该溶液可浓缩成一层:

def budMapList = (budProp + budCyExp).groupBy { it.ACCTCODE }.collect { code, mapList -> mapList.sum() }

非常感谢你。这正是我所需要的。你是对的,名单没有完美地排列,他们没有,但我想一个答案会告诉我正确的方向,我必须找出其余的,但你给了我我所需要的一切。非常感谢。这正是我所需要的。你是对的,列表没有完美地排列,它们没有,但我想一个答案会告诉我正确的方向,我必须找出其余的,但你给了我所有这些都需要的东西。同样感谢这个答案,我喜欢一个问题有多个解决方案,这有助于我了解更多。唯一使Nathan的解决方案更适用的是,它将返回ACCTCODE、BUDGET和cYBudget,而不管ACCTCODE值是否在这两个列表中。例如,budProp可能有第三组在budCyExp中不存在的ACCTCODE和BUDGET,因此它将返回[ACCTCODE:value,BUDGET:value,cYBudget:null]。我没有足够的声誉分数来标记你的答案是否有用,但如果可以的话,我会的;我并不是来讨论这些问题的。此外,如果其他人喜欢这个答案,他们会大惊小怪的。Java/Groovy默认映射语义确保如果从没有键的映射请求项,映射将返回null。因此,即使在映射中不会显式定义条目
cYBudget:null
,如果您尝试访问密钥,结果也将为null:
answerMap.cYBudget==null
。因此,从数据访问的角度来看,结果是一样的。同样感谢这个答案,我喜欢一个问题有多种解决方案,它帮助我了解更多。唯一使Nathan的解决方案更适用的是,它将返回ACCTCODE、BUDGET和cYBudget,而不管ACCTCODE值是否在这两个列表中。例如,budProp可能有第三组在budCyExp中不存在的ACCTCODE和BUDGET,因此它将返回[ACCTCODE:value,BUDGET:value,cYBudget:null]。我没有足够的声誉分数来标记你的答案是否有用,但如果可以的话,我会的;我并不是来讨论这些问题的。此外,如果其他人喜欢这个答案,他们会大惊小怪的。Java/Groovy默认映射语义确保如果从没有键的映射请求项,映射将返回null。因此,即使在映射中不会显式定义条目
cYBudget:null
,如果您尝试访问密钥,结果也将为null:
answerMap.cYBudget==null
。因此,从数据访问的角度来看,结果是相同的。