20

Groovy に 2 つのマップが[a: 1, b: 2]あり[b:1, c:3]、それらから 3 つ目のマップを作成したいと考えています[a: 1, b: 3, c: 3]。それを行うGroovyコマンドはありますか?

編集: 3 番目のマップの値は、キーが同一の場合、最初の 2 つのマップの値の合計であることに注意してください。

ありがとう

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() ]
}

エピデミアンの回答をヒントに、複数のマップを処理するメソッドを作成することもできます

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]それらのそれぞれが結果に追加されます。

すべての変換を 1 つの式にまとめて「より機能的」にしたい場合の別のオプションは、最初にエントリをキーでグループ化し、次に値を合計することですが、読みにくいと思います。

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同じケイを持ち、代わりに値にリストの合計を持つ別のものにマップする変換を返します。

于 2012-04-12T20:17:20.927 に答える
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
def merge(map1, map2) { 
    def add = { map, entry -> map << entry }
    map2.inject(map1.inject([:], add), add)
}
于 2015-03-10T12:32:12.703 に答える
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 に答える