Groovy groupby List generated from Map values

Viewed 333

This is the List that I have

List a = ["Sep->Day02->FY21;Inter01","Sep->Day02->FY21;Inter02","Sep->Day02->FY21;Inter03","Sep->Day01->FY21;Inter18","Sep->Day01->FY21;Inter19"]

I am trying to group this and generate a new string

Expected result

"Sep->Day02->FY21",Inter01:Inter03
"Sep->Day01->FY21",Inter18:Inter19

Tried to do this

List a = ["Sep->Day02->FY21;Inter01","Sep->Day02->FY21;Inter02","Sep->Day02->FY21;Inter03","Sep->Day01->FY21;Inter18","Sep->Day01->FY21;Inter19"] 
List b = []
a.each{
b.add(it.split(";"))
}
def c = b.groupBy{it[0]}
println c
c.each{
 k, v -> println "${v}"
}

I cant find a way to get the range of Inter01:Inter03 in the string. Please advice.

EDIT

The solution provided by Marmite works in the groovy console as expected. The list I am generating is from values in a map.

a.add(map[z]) Where z is the key.

When I am trying to use it, it gives me max and min method not found errors.

Tried using map[z].toString(). Still the same. Is the fact that the values are from a map affecting the same?

Code Snippet Below is how I generate the map

def map = [:]

itr.each{
def Per = it.getMemberName("Period") //getMemberName is a product specific function . Sample output May
def Day = it.getMemberName("Day") //Day01 sample output
def Hour = it.getMemberName("Hour") //Interval01 sample output
def HourInt = it.getMemberName("Hour").reverse().take(2).reverse()
def Year = it.getMemberName("Years")
map.put(it.DataAsDate.format("dd/MM/yyyy")+"-"+Hour,Year+"->"+Per+"->"+Day+";"+HourInt)
}

Below is where I generate the List


def OSTinterval = OST.reverse().take(2).reverse() as Integer //This creates 01 out of Interval01
def OETinterval = OET.reverse().take(2).reverse() as Integer //This creates 03 out of Interval03

D1 = new Date(OSDDay)
D2 = new Date(OEDDay)
if (D1 == D2)
{
(OSTinterval..OETinterval).each
{inter ->
z = OSDDay+"-"+"Interval"+inter.toString().padLeft(2,'0')
coll.add(map[z].toString())
}
}
else
{
(D1..D2).each { 
if (it == D1){
(OSTinterval..48).each
{inter ->
z = OSDDay+"-"+"Interval"+inter.toString().padLeft(2,'0')
coll.add(map[z].toString())
}

1 Answers

Basically you are looking for min and max after grouping.

I'm using a bit simplified data to focus on the processing:

def a = ['D02;I01','D02;I02','D02;I03','D01;I18','D01;I18']

println  a.collect{it.split(";")}
          .groupBy{it[0]}
          .collect{k,v -> [k,v.collect {it[1]}]}
          .collect{[it[0],"${it[1].min()}:${it[1].max()}"]}
          .collect{it.join(',')}

returns a list of the keys with the min and max of the values

[D02,I01:I03, D01,I18:I18]

result after groupBy

[D02:[[D02, I01], [D02, I02], [D02, I03]], D01:[[D01, I18], [D01, I18]]]

The next collect removes the duplicated keys

[[D02, [I01, I02, I03]], [D01, [I18, I18]]]

Finally you find the min and max of the lists

[[D02, I01:I03], [D01, I18:I18]] 
Related