Assuming I have list of maps in Groovy:
def listOfMaps = [
[k: 1, n: 'Name1', d1: 'a', d2: 'b'],
[k: 2, n: 'Name2', d1: 'c', d2: 'd'],
[k: 1, n: 'Name3', d1: 'e', d2: 'f'],
[k: 4, n: 'Name4', d1: 'g', d2: 'h']]
I need to find if there exist (or not) items, where k
is equal, but n
is not. E.g. in this case we have two map records with "k" = 1 and "n" is 'Name1' and 'Name3'. How can I find such data?
I suppose I should group by "k" and count distinct values in "n", if there are more than 1 unique values in "n" for certain "k" - we found such data.
I'm completely stuck so any help will be appreciated.
Thanks
If you wanted to do it that way, iterate over map. keySet() and the rest will work as you expected. It should work if you use s. key & s.
Maps don't have an order for the elements, but we may want to sort the entries in the map. Since Groovy 1.7. 2 we can use the sort() method which uses the natural ordering of the keys to sort the entries. Or we can pass a Comparator to the sort() method to define our own sorting algorithm for the keys.
Maps are generally used for storing key-value pairs in programming languages. You have two options to declare a map in groovy. First option is, define an empty map and put key-value pairs after. Second option is declaring map with default values.
2. Creating Groovy Maps. We can use the map literal syntax [k:v] for creating maps. Basically, it allows us to instantiate a map and define entries in one line.
EDIT
Now I've worked out what you meant, here's the code:
listOfMaps.groupBy {
it.k }.
values().
findAll { l ->
l.size() > 1 && (l.size() == l.unique { e -> e.n }.size())
}
At the beginning the list is grouped by k
element, then among the values we search for lists with size higher than 1 and which size is equal to count of unique n
elements. It works correctly.
OLD ANSWERS
You can try the combination of findAll
and unique
:
def listOfMaps = [
[k: 1, n: 'Name1', d1: 'a', d2: 'b'],
[k: 2, n: 'Name2', d1: 'c', d2: 'd'],
[k: 1, n: 'Name3', d1: 'e', d2: 'f'],
[k: 4, n: 'Name4', d1: 'g', d2: 'h'],
]
listOfMaps.findAll { it.k == 1 }.unique { it.n }
Or with groupBy
:
listOfMaps.groupBy { it.k }[1].unique { it.n }
In groovy there are many ways of doing it ;)
If you are interested in a reducing version, this one builds a map of k
to a set of n
s.
def r = listOfMaps.inject([:].withDefault{[].toSet()}) { m, it ->
m.get(it.k).add(it.n); m }
println r.findAll{ it.value.size()>1 }
// => [1:[Name3, Name1]]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With