It's real easy to sort a list of numbers
assert [1,2,3,4] == [3,4,2,1].sort()
Or even strings
assert ['Chad','James','Travis'] == ['James','Travis','Chad'].sort()
But this was my example
class Person {def list = [new Person(id: '1', name: 'James'),new Person(id: '2', name: 'Travis'), new Person(id: '3', name: 'Chad')]
String id
String name
}
list.sort() returns James, Travis, Chad
The solution is ridiculously simple (not that I thought the previous sort would work; I have to be realistic; groovy can't do everything for me).
list.sort{it.name} will produce an order of Chad, James, Travis.
In the previous example note the use of the sort closure sort {} verses the sort() method.
Now I am not sure, off the top of my head and without a Groovy book handy, the simplest way to sort case insensitive.
assert ['a1','A1'] == ['A1,'a1'].sort{fancy closure}
You sir, are my friggin' hero. I've been messing with trying to create my own tag, etc for this, and you have the answer!
ReplyDeleteThank you 10 times over!
Your post really helped me, James.
ReplyDeleteI found myself wanting case-insensitive sorting, too, so here's what worked for me (I tweaked your test data to make it more obvious):
assert ['a1', 'A2', 'a3'] == ['A2','a3', 'a1'].sort { a, b -> a.compareToIgnoreCase b }
Very helpful indeed - thanks for posting!
ReplyDeleteTo no surprise, your post showed up in my google search for groovy list sorting ...
ReplyDeletethanks again buddy
- Sturtz
Thank you very much :-)
ReplyDeleteGREAT! Thank you!
ReplyDeleteWouldn't a better solution be to implement Comparable and override compareTo method?
ReplyDeletethx bro :)
ReplyDeleteI looked for this for 2 days!!
ReplyDeleteThanks
Good post indeed, but in most cases I think the Anonymous poster from March 1, 2009 9:44 PM had the better solution as it's more reusable.
ReplyDelete"Wouldn't a better solution be to implement Comparable and override compareTo method?"
This is my solution:
ReplyDeleteclass Person {
String id
String name
}
def list = [new Person(id: '1', name: 'James'),new Person(id: '2', name: 'Travis'), new Person(id: '3', name: 'Chad'),
new Person(id:'4', name:'angel')]
println list.name
// If you want to sort with Case sensitive, uncomment sort with spaceship operator <==> and comment the sort with compareToIgnoreCase
// list.sort { p1, p2 -> p1.name <=> p2.name }
list.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }
println list.name
thanks for posting! It helped me just now and I bet it has helped far more than those who took the time to comment.
ReplyDeleteYeah but, what if you wanted to reverse the sort order?
ReplyDeleteMuch appreciated dude!!
ReplyDeleteTo reverse sort order just add a dash before it. I just tried this (but for numeric values) and it worked.
ReplyDeletelist.sort{-it.name}
//Henrik Sjostrand
Nice, just what I was looking for. Thanks James.
ReplyDeleteTo sort a list of map entries, use either:
ReplyDeletelist.sort{it.key}
or
list.sort{it.value}
Thanks for the great job.Can you give us an exmple of how do we apply this on GSPs?
ReplyDeleteGreat Job there. Can you give also show us how we can apply this to our table listing on GSPs?
ReplyDeleteFantastic, many thanks.
ReplyDelete/Mattias
This post helped me greatly. Thanks. For reverse order I found that you need to add .reverse() to ones sort closure.
ReplyDeletee.g.
myList.sort{ it.date}.reverse()
Is there any way to specify the order like in mysql we can specify "order by field(id, 2,3,1,4)". Can we specify such order on a property of domain class in grails criteria ?
ReplyDeleteTo sort case sensitive:
ReplyDeleteassert ["b","A","C","d"].sort() == ["A","C","b","d"]
To sort case insensitive:
assert ["b","A","C","d"].sort{it.toLowerCase()} == ["A","b","C","d"]
thanks alot!
ReplyDeleteThank you , it is still helping us.
ReplyDeleteAmazing... I find more and more answers to my questions on your blog. Big fan already. Thanks a bunch.
ReplyDeleteThank you very much. This really helped a lot.
ReplyDeleteAnon in Feb asked about sorting with multiple db fields.
ReplyDeleteI just did this, here's my solution. Elegance upgrades welcome!
things.sort {thing1, thing2-> (thing1.field1<=>thing2.field1)?:(thing1.field2<=>thing2.field2)}
Love the terminology ... "Elvis and the spaceships"
Note, I actually wanted to reverse order the second field, so I negated the second sort:
things.sort {thing1, thing2-> (thing1.field1<=>thing2.field1)?:-(thing1.field2<=>thing2.field2)}
This is for two db fields ... multiple? does the structure hold up? for you to try if you want.
this blog even helped me...thanks a ton...
ReplyDeleteHOw to sort this array value??
ReplyDeletedata = [[1,23],[1,13],[2,543],[2,573]]
I want to sort on the basis of second value of array like
[[1,13],[1,23],[2,543],[2,573]]
Thanks
to Sonu
ReplyDelete[[1,23],[1,13],[2,543],[2,573]].sort {a, b -> a[1].compareTo(b[1])}
Incredibly helpful. Thank you so much.
ReplyDeleteIf you want case insensitive searching but also protection from nulls, try:
ReplyDelete.sort {it.name?.toLowerCase()}
This continues to be very valuable information. Thanks for posting it.
ReplyDeleteFive years later, James's post is still the best thing on the web for Groovy newcomers, like me.
ReplyDeleteAfter I used this to get my sorting done, I tried it again, but made the very mistake that the original post had warned about--using parentheses instead of curly braces (sorry, James, I need to read more slowly).
Watch out for this mistake -- it produces mysterious error messages, such as "Cannot get property 'name' on null object" or "No such property: it for class".
This experience prodded me into figuring out what the curly-brace syntax was actually doing
(see http://groovy.codehaus.org/groovy-jdk/java/util/Collection.html#sort(java.util.Comparator) )
which in turn suggests what I believe is the simplest solution to case-insensitive sorting (at least it worked for me):
list.sort {it.name.toLowerCase()}
Oops! I now see that Anonymous beat me to that case-insensitive solution by about five months -- and with more robust code too.
ReplyDeleteOops again. The documentation link I posted should have been to the overloading of sort() that uses a closure:
ReplyDeletehttp://groovy.codehaus.org/groovy-jdk/java/util/Collection.html#sort(groovy.lang.Closure)
WOW, that was simple, thanks!
ReplyDeleteyou just saved me a bunch of extra work. thank you
ReplyDelete