Sort list in natural order in Groovy

4.6k views Asked by At

Trying to sort(ascending order) the list of strings in natural / human readable order. Something like below.

def list = ['f3', 'f10', 'f1', 'f12', 'f2', 'f34', 'f22','f20','f50', 'f5']
list.sort()

I could find sample java code in GitHub. But looking for groovy way. Any help is appreciated.

Desired output:

f1, f2, f3, f5, f10, f12, f20, f22, f34, f50
3

There are 3 answers

3
daggett On BEST ANSWER
def list = ['f3', 'f10', 'f1', 'f12', 'f2', 'f34', 'f22','f20','f50', 'f5']
list.collect{ (it=~/\d+|\D+/).findAll() }.sort().collect{ it.join() }

Result:

[f1, f2, f3, f5, f10, f12, f20, f22, f34, f50]
0
Szymon Stepniak On

You can also use following comparator:

list.sort { a,b -> a[0] <=> b[0] == 0 ?
        (a[1..-1] as int) <=> (b[1..-1] as int) :
        a[0] <=> b[0]
}

It compares literals in the first place and when they are equal it compares numeric part. Using this method with list like:

['f3', 'f10', 'f1', 'f12', 'f2', 'f34', 'f22','f20','f50', 'f5', 'g1', 'g11', 'z0', 'a00', 'a01']

generates following result:

[a00, a01, f1, f2, f3, f5, f10, f12, f20, f22, f34, f50, g1, g11, z0]
6
dmahapatro On
def list = ['f3', 'f10', 'f1', 'f12', 'f2', 'f34', 'f22','f20','f50', 'f5', 'f9']
list.sort { it[1..-1] as int }​

Results:

[f1, f2, f3, f5, f9, f10, f12, f20, f22, f34, f50]