The Kaptain on … stuff

24 Oct, 2009

Groovy reverse map sort done easy

Posted by: TheKaptain In: Development

Sorting a Map by value with Groovy is very simple, due to the added ‘sort’ method on the Map interface.
[groovy language=”language="true”]
def map = [a:3, b:2, c:1]
map = map.sort {it.value}
assert map == [c:1, b:2, a:3]
[/groovy]

Turns out doing a reverse sort on a Map by values is almost as easy.
[groovy language=”language="true”]
def map = [a:1, b:2, c:3]
map = map.sort {a, b -> b.value <=> a.value}
assert map == [c:3, b:2, a:1]
[/groovy]

Using the spaceship operator (‘< =>‘) you can define a very terse syntax for accessing ‘compareTo’, as long as the values in the map implement Comparable that is.
Nice!

5 Responses to "Groovy reverse map sort done easy"

1 | Keegan

January 13th, 2010 at 7:27 am

Avatar

Your assertion passes, but it doesn’t compare order. I tried this in Groovy 1.6.7 and 1.7.0 and the order was unchanged from the original. (Compared println of the map to the original). Am I missing something?

2 | TheKaptain

January 13th, 2010 at 8:02 am

Avatar

Not sure exactly what you mean here Keegan…
The sort method returns a new Map instead of sorting the existing map – perhaps that’s what you’re seeing if you’re still examining the original Map?
Adding some println’s to the code above I see these results:
Sorting by key before sort – a:3, b:2, c:1
Sorting by key after sort – c:1,b:2,a:3
Sorting by value before sort – a:1, b:2, c:3
Sorting by value after sort – c:3,b:2,a:1

3 | Keegan

January 13th, 2010 at 12:43 pm

Avatar

Oops, I must have forgot to do the reassignment. Sorry about that. My statement about the asserts is still true, as someone pointed out to me today (I made the same mistake). For example, put this at the end

assert map == [c 1=”a:1,” 2=”b:2″ language=”:3,”][/c]

and you’ll see it too passes. Your assert is good for demonstrating, just something to keep in mind.

4 | Keegan

January 13th, 2010 at 5:14 pm

Avatar

Sorry, looks like wordpress cut my example off, what I had in square brackets was a:3, c:1, b:2

5 | TheKaptain

January 13th, 2010 at 8:37 pm

Avatar

Yeah, wordpress can sometimes be too ‘helpful’ that way. And you’re absolutely right – shame on me for assuming that order was part of the comparison; the assertion I’ve shown is only relevant as far as the items in the map, not their order. I think you’ll find this, however, does properly check that condition.

def map = [a:3, b:2, c:1]
map = map.sort {it.value}
assert (map.keySet() as List) == [‘c’,’b’,’a’]

Comment Form