Search code examples
groovymapreducefunctional-programming

Groovy: map reduce list of maps


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


Solution

  • 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 ;)