How to sort a list of classes by defined field in alphanumeric based on numbers in Groovy?

53 Views Asked by At

I need to check the specific sorting. There is list of classes:

[
no = '1'
field = 'FEE_HIG_R_test1234_2',

no = '2'
field = 'FEE_HIG_R_test1234_11',

no = '3'
field = 'FEE_HIG_R_test1234_10',

no = '4'
field = 'FEE_HIG_R_test1234_1',

no = '5'
field = '06633-146944-0000036012',

no = '6'
field = '06633-155867-0000051910',

no = '7'
field = '06687-250844-00002544203'
]

I have to sort by field in alphanumeric based on numbers and get the result like:

[
no = '5'
field = '06633-146944-0000036012',

no = '6'
field = '06633-155867-0000051910',

no = '7'
field = '06687-250844-00002544203',

no = '4'
field = 'FEE_HIG_R_test1234_1',

no = '1'
field = 'FEE_HIG_R_test1234_2',

no = '3'
field = 'FEE_HIG_R_test1234_10',

no = '2'
field = 'FEE_HIG_R_test1234_11'
]

I tried: result.sort{ a,b -> (((a.field =~ /\d+/)[-1] as Integer) <=> ((b.field =~ /\d+/)[-1] as Integer)) }

but result was:

[
no = '4'
field = 'FEE_HIG_R_test1234_1',

no = '1'
field = 'FEE_HIG_R_test1234_2',

no = '3'
field = 'FEE_HIG_R_test1234_10',

no = '2'
field = 'FEE_HIG_R_test1234_11',

no = '5'
field = '06633-146944-0000036012',

no = '6'
field = '06633-155867-0000051910',

no = '7'
field = '06687-250844-00002544203'
]

Could someone help?

1

There are 1 best solutions below

2
injecteer On

Something like this one-liner:

def data = [
  'FEE_HIG_R_test1234_2',
  '06687-250844-00002544204',
  '06687-250844-00002544203',
  '06687-250844-00002544202',
  'FEE_HIG_R_test1234_1',
  '06633-146944-0000036012',
  '06633-155867-0000051910',
  'FEE_HIG_R_test1234_11',
  'FEE_HIG_R_test1234_10',
]

def result = data.sort{ 
   it ==~ /\d+-\d+-\d+/ 
      ? it.replaceAll( '-', '' ).toBigDecimal() 
      : 10000000000000000000000 + ( it =~ /\d+/ )[ -1 ].toInteger() 
}

assert result.join( '\n' ) == '''\
06633-146944-0000036012
06633-155867-0000051910
06687-250844-00002544202
06687-250844-00002544203
06687-250844-00002544204
FEE_HIG_R_test1234_1
FEE_HIG_R_test1234_2
FEE_HIG_R_test1234_10
FEE_HIG_R_test1234_11'''

The 1000000... + is needed to push the smaller numbers in strings like FEE_HIG_R_test1234_1 further to the right.