victor victor - 3 months ago 9
Groovy Question

How to combine a list of objects to a map of list with a custom key based on a field value in Groovy?

Hi I'm new to Groovy and have been trying this out but could not come up with a correct solution.

Basically I have a list of objects that i would need to correlate part of a specific field and put it in a map with a transformed key. Given example below, I need correlate the values of the third field by the first four characters (e.g. key3,key4) and put them in a map. So all key3 objects and key4 objects in a separate map and combine them in 1 map with key3 and key4 as the keys and their original values in a list.

Foo[] foo = [
["field1a", "field2a", "key3a"],
["field1b", "field2b", "key3b"],
["field1c", "field2c", "key4c"]
]


into

result = [
"key3":[
["field1a", "field2a", "key3a"],
["field1b", "field2b", "key3b"]
],
"key4":[
["field1c", "field2c", "key4c"]
]
]


So far i've been able to get the unique keys by using a combination of collect(), substring() and unique(), but i am unable to build the map properly. I've used collectEntries() but it only creates a map of the object and not a map of lists.

If anyone can point me in the right direction it would really be a big help. Thanks!

Answer

Using groupBy.

assert foo.groupBy { it[-1][0..-2] } == [
    key3:[
        ['field1a', 'field2a', 'key3a'], 
        ['field1b', 'field2b', 'key3b']
    ], 
    key4:[
        ['field1c', 'field2c', 'key4c']
    ]
]

Explanation:
Group by the third/last element in the list it[-1] but only consider the substring key3, hence it[-1][0..-2]