Reputation: 13
i want to group a list of objects by a dynamic list of fields (given by name). I'll try to explain it with an example.
Let's say I have a class looking similar to this:
def SomeClass{
String one
String two
String three
String four
//etc..
}
Now I have a changeable list of 1-4 field names, therefore hardcoding is not an option, like this:
def fields = ["one", "two"]
//or
def fields2 = ["two", "three", "four"]
I want to sort lists of SomeClass
, and as result I need a map with a list of values as key and the objects as value; Looking like this:
//group by fields:
def result = [[someClass.one, someClass.two]:[List<SomeClass>],...]
//group by fields2:
def result2 = [[someClass.two, someClass.three, someClass.four]:[List<SomeClass>],...]
I tried splitting the fields and create closures for .groupBy()
, but I retrieve a nested Map.
With .collectEntries()
i'm not sure how to pass a changeable list of fields to the closure.
The lists I want to sort contain around 500-10000 elements, with 1-4 fields I want to group by.
Upvotes: 1
Views: 704
Reputation: 171084
You can use groupBy
with a Closure
and collect
your fields inside it:
import groovy.transform.*
@Canonical
class SomeClass{
String one
String two
String three
}
List<SomeClass> list = [
new SomeClass('a', '1', 'i'),
new SomeClass('a', '1', 'ii'),
new SomeClass('a', '2', 'i'),
new SomeClass('a', '2', 'ii'),
new SomeClass('a', '3', 'i'),
]
def fields = ['one', 'two']
Map<List<String>,List<SomeClass>> grouped = list.groupBy { o -> fields.collect { o."$it" } }
assert grouped == [
['a', '1']:[new SomeClass('a', '1', 'i'), new SomeClass('a', '1', 'ii')],
['a', '2']:[new SomeClass('a', '2', 'i'), new SomeClass('a', '2', 'ii')],
['a', '3']:[new SomeClass('a', '3', 'i')]
]
Upvotes: 2