20

我在 Groovy 中有两张地图,[a: 1, b: 2][b:1, c:3]想从中创建第三张地图[a: 1, b: 3, c: 3]。是否有一个 Groovy 命令可以做到这一点?

编辑:请注意,如果键相同,则第三个映射中的值是前两个映射中的值的总和。

谢谢

4

7 回答 7

17

另一个解决方案是:

def m1 = [ a:1, b:2 ]
def m2 = [ b:1, c:3 ]

def newMap = [m1,m2]*.keySet().flatten().unique().collectEntries {
  [ (it): [m1,m2]*.get( it ).findAll().sum() ]
}

epidemian的回答为灵感,也可以写个方法来处理多张地图

def m1 = [a: 1, b: 2]
def m2 = [b: 1, c: 3]

def combine( Map... m ) {
  m.collectMany { it.entrySet() }.inject( [:] ) { result, e ->
    result << [ (e.key):e.value + ( result[ e.key ] ?: 0 ) ]
  }
}

def newMap = combine( m1, m2 )
于 2012-04-12T19:57:50.870 回答
13

这应该适用于任意数量的地图:

def maps = [[a: 1, b: 2], [b:1, c:3]]

def result = [:].withDefault{0}
maps.collectMany{ it.entrySet() }.each{ result[it.key] += it.value }

assert result == [a: 1, b: 3, c: 3]

maps.collectMany{ it.entrySet() }表达式返回一个映射条目列表,例如[a=1, b=2, b=1, c=3],然后将每个条目添加到结果中。

另一种选择是,如果您想将所有转换保留为一个表达式并使其“更具功能性”,则首先按键对条目进行分组,然后对值求和,但我认为它的可读性较差:

def result = maps.collectMany{ it.entrySet() }
    .groupBy{ it.key }
    .collectEntries{[it.key, it.value.sum{ it.value }]}

groupBy部分返回表单的映射,[a:[a=1], b:[b=2, b=1], c:[c=3]]然后将collectEntries映射转换为具有相同 kays 但具有值中列表总和的另一个映射。

于 2012-04-12T20:17:20.927 回答
4

以下示例演示了将两个映射添加到第三个映射m3

Map m1 = [ a:1, b:2 ];
Map m2 = [ b:1, c:3 ];
Map m3 = [:];
m3 << m1
m3 << m2
于 2014-09-10T04:53:46.630 回答
3

一个不错的方法是使用扩展运算符:

def m1 = [ a:1, b:2 ]
def m2 = [ b:1, c:3 ]
def m3 = [ *:m1, *:m2 ]

println "m1 = $m1"
println "m2 = $m2"
println "m3 = $m3"

*信用: http: //mrhaki.blogspot.ch/2009/09/groovy-goodness-spread-operator.html

上面的代码在 groovysh 中不起作用,但在 groovy 控制台中很好。(适用于 1.8 版)

于 2013-01-09T13:23:01.950 回答
2

我认为没有现成的方法,也许使用类似的方法:

def m1 = [a: 1, b: 2]
def m2 = [b: 1, c: 3]
def newMap = (m1.keySet() + m2.keySet()).inject([:]) { 
    acc, k -> acc[k] = (m1[k] ?: 0) + (m2[k] ?: 0); acc 
}
于 2012-04-12T19:44:13.630 回答
0

这样做:

Map additionJoin( Map map1, Map map2 )
{
  def result = [:];
  result.putAll( map1 );
  result.putAll( map2 );

  result.each { key, value ->
    if( map1[key] && map2[key] )
    {
      result[key] = map1[key] + map2[key]
    }
  }

  return result;
}

def a = [a: 1, b: 2]
def b = [b:1,c:3]

def c = additionJoin( a, b )

println c
于 2012-04-12T19:46:00.460 回答
0
def merge(map1, map2) { 
    def add = { map, entry -> map << entry }
    map2.inject(map1.inject([:], add), add)
}
于 2015-03-10T12:32:12.703 回答