次のようなマップのコレクションがあります。
def list = [
[key1: 'ABC', key2: 3, value: 1.01],
[key1: 'ABC', key2: 4, value: 1.02],
[key1: 'ABC', key2: 4, value: 1.03],
[key1: 'DEF', key2: 3, value: 1.04]]
一意の key1 値と key2 値の値をグループ化して合計し、結果が階層になる、このような結果を得ようとしています。
['ABC':[[key2: 2, value: 1.01]
[key2: 4, value: 2.05]], //note values are added
'DEF':[[key2: 3, value: 1.04]]
]
1 つのキーを持つマッピング ルーチンの例はたくさんありますが、複数のキーを使用する場合にこれらを折りたたむ最良の方法は何ですか?
私が考えた 1 つの解決策は、groupby を使用して、最初のキーでグループ化されたリストを取得することでした。次に、各要素のサブリストで結合または削減を実行する必要があるという問題があります。
list.parallel
.map{it}
.groupBy{it.key1}
この時点で、グループ化されたマップの .value() を削減したいのですが、チェーン内では実際には実行できません
また、ここの例のように機能する結合を使用しようとしました。ただし、結合がマップを取得した場合は、さらに結合したいようです。
def result = list.parallel
.map{[it.key1, it]}
.combine({-> [:]}) { map, v -> println "$map - $v = ${v.getClass()}"
map[v.key2] = map[v.key2]?:0 + v.value
map
}
次に、マップを単純に縮小するオプションがありますが、縮小ルーチンは、ネストされたマップを組み合わせる非常に複雑な獣になります。だから、もっと単純なものがあるのか 、それとも単純にreduceルーチンを実行して複雑なマップを組み合わせる必要があるのか 疑問に思っています。
list.parallel
.map{[(it.key1):it]}
.reduce([:]) { a, b ->
complexMapCombiner(a, b)
}