Groovy に 2 つのマップが[a: 1, b: 2]
あり[b:1, c:3]
、それらから 3 つ目のマップを作成したいと考えています[a: 1, b: 3, c: 3]
。それを行うGroovyコマンドはありますか?
編集: 3 番目のマップの値は、キーが同一の場合、最初の 2 つのマップの値の合計であることに注意してください。
ありがとう
Groovy に 2 つのマップが[a: 1, b: 2]
あり[b:1, c:3]
、それらから 3 つ目のマップを作成したいと考えています[a: 1, b: 3, c: 3]
。それを行うGroovyコマンドはありますか?
編集: 3 番目のマップの値は、キーが同一の場合、最初の 2 つのマップの値の合計であることに注意してください。
ありがとう
さらに別の解決策は次のとおりです。
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 )
これは、任意の数のマップで機能するはずです。
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
同じケイを持ち、代わりに値にリストの合計を持つ別のものにマップする変換を返します。
良い方法は、スプレッド演算子を使用することです。
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の場合)
これには既製の方法はないと思います。おそらく次のようなものを使用してください。
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
}
def merge(map1, map2) {
def add = { map, entry -> map << entry }
map2.inject(map1.inject([:], add), add)
}
これはそれを行います:
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