3

我只是在探索 groovy 时遇到了这个问题,我有一个地图,我想从该地图中获取具有相同值的键。

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

是否有可能只获得具有相同值的键,我想从这个例子中得到一个带有值的列表:

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

我有一个解决这个问题的方法,而且代码很长,我只是想知道是否可以findAll在 Map 中解决这个问题。我很难计算地图中的值。

感谢您分享您的想法。

4

2 回答 2

7

如果您知道需要键的值,则可以使用该findAll方法获取具有该值的所有条目,然后keySet使用 splat 运算符或使用 splat 运算符获取键*.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}。最后一个条件导航和 splat 运算符?.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 回答