3

groovyを探索しているときにこの問題を思いついたのですが、マップがあり、そのマップから同じ値のキーを取得したいと思いました。

Map maps = ['a': 10, 'b': 10, 'c': 11, 'd': 12]

同じ値のキーのみを取得することは可能ですか。この例から取得したいのは、値のリストです。

List keys = ['a','b']

私はこの問題の解決策を持っています、そしてそれはコードの長い行です、私はfindAllマップでこれを使用してこれを解決することが可能かどうか疑問に思っています。マップの値を数えるのに苦労しています。

あなたのアイデアを共有してくれてありがとう。

4

2 に答える 2

7

キーが必要な値がわかっている場合は、findAllメソッドを使用してその値を持つすべてのエントリを取得keySetし、splat 演算子を使用して、または as を使用してキーを取得でき*.keyます。

def keysForValue(map, value) {
    map.findAll { it.value == value }*.key
}

def map = ['a': 10, 'b': 10, 'c': 11, 'd': 12]

assert keysForValue(map, 10) == ['a', 'b']
assert keysForValue(map, 12) == ['d']
assert keysForValue(map, 13) == []

繰り返されるキーを持つ値がわからず、繰り返される値を持つキーを取得することだけが必要な場合 (存在する場合)、次のようなことを試すことができます。

def getKeysWithRepeatedValue(map) {
    map.groupBy { it.value }.find { it.value.size() > 1 }?.value*.key
}

最初にマップ エントリを値でグループ化するため、map.groupBy { it.value }マップ例の結果は になり[10:[a:10, b:10], 11:[c:11], 12:[d:12]]ます。次に、そのマップ内で、値として複数の要素を持つリストを持つ最初のエントリを見つけます。そのエントリは、複数のキーが関連付けられている値に対応しています。の結果は.find { it.value.size() > 1 }、マップ エントリになります10={a=10, b=10}。最後の条件付きナビゲーションとスプラット演算子?.value*.keyは、そのエントリが存在する場合にその値を取得し、その値のキーを取得することです。使用法:

assert getKeysWithRepeatedValue(['a': 10, 'b': 10, 'c': 11, 'd': 12]) == ['a', 'b']

// If no value has more than one key, returns null:
assert getKeysWithRepeatedValue(['a': 10, 'c': 11, 'd': 12]) == null

// If more than one value has repeated keys, returns the keys that appear first:
assert getKeysWithRepeatedValue(['a': 10, 'b': 11, 'c': 10, 'd': 11]) == ['a', 'c']
于 2012-11-20T05:35:03.227 に答える
5

もしかして

Map maps = ['a': 10, 'b': 10, 'c': 11, 'd': 12]

多分?簡単ですが、マップは要素の順序を保持しません。次のコマンドを使用して、キーのリストを順不同で取得できます。

List output = maps.keySet() as List

または、マップを逆にして、各値のキーのリストを見つけたい場合は、これを使用できます。

Map output = maps.groupEntriesBy {
   it.value
}.each {
   it.value = it.value.collect {
      it.key
   }
}
于 2012-11-20T02:50:09.780 に答える