Search code examples
groovy

Groovy - mapping with groupBy and counting instances of an element within the result


I am starting with a collection as such:

def finalDocument = [[problem:problem1,fixed:true], [problem:problem1,fixed:false],[problem:problem1,fixed:false],[problem:problem2,fixed:true],[problem:problem2,fixed:false]]

What I want to do is create a map containing the problem and counts of how many are fixed, like this:

["problem1":[true:1,false:2],"problem2":[true:1,false:1]]

My end goal is to produce a percentage of fixed vs total for each problem

I'm trying to use groupBy to achieve this:

def output = finalDocument.groupby({it.problem},{it.fixed})

The resulting map is nested correctly but it gives me a list of the documents rather than a count of each, which I'm not sure how to achieve (I'm new to Groovy and scripting in general).


Solution

  • I'd put it like so:

    def finalDocument = [[problem:'problem1',fixed:true], [problem:'problem1',fixed:false],[problem:'problem1',fixed:false],[problem:'problem2',fixed:true],[problem:'problem2',fixed:false]]
    
    def res = finalDocument.groupBy{ [ it.problem, it.fixed ] }.inject( [:].withDefault{ [:] } ){ acc, grp, vals -> acc[ grp.first() ][ grp.last() ] = vals.size(); acc }
    
    assert res.toString() == '[problem1:[true:1, false:2], problem2:[true:1, false:1]]'