Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting keys with duplicate values in a Groovy map

I just came up with this problem while exploring groovy, I have a Map and i wanted to get the keys with the same values from that map.

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

is it possible to get only the keys with same values, what i wanted to get from this example is a list with values:

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

I have a solution for this problem and it's a long line of codes, I'm just wondering if it is possible to solve this using findAll in Map. I'm having a hard time counting the values in the map.

thanks for sharing your ideas.

like image 985
antibry Avatar asked Oct 20 '25 11:10

antibry


1 Answers

If you know which value you need the keys for, then you can use the findAll method to get all the entries that have that value and then get the keys with keySet or by using the splat operator 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) == []

In case you don't know which value should have the repeated keys, and all you want is to get the keys that have a repeated value (if there's any), you can try something like:

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

It first groups the map entries by value, so the result of map.groupBy { it.value } for the example map is [10:[a:10, b:10], 11:[c:11], 12:[d:12]]. Then it finds the first entry in that map that has a list with more than one element as a value; that entry corresponds with the value that has more than one key associated with it. The result of .find { it.value.size() > 1 } would be the map entry 10={a=10, b=10}. The last conditional navigation and splat operator ?.value*.key is to get the value of that entry in case it exists and then get keys of that value. Usage:

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']
like image 89
epidemian Avatar answered Oct 23 '25 07:10

epidemian



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!