Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reverse the sort of a Groovy collection?

I am sorting a list based on multiple fields.

sortedList.sort {[it.getAuthor(), it.getDate()]}

This works fine, but I want the date to be reversed and reverse() does not work.

How do I sort the author in ascending order but sort the date in descending (reverse) order?

Example of what I want:

Author    Date
Adam      12/29/2011
Adam      12/20/2011
Adam      10/10/2011
Ben       11/14/2011
Curt      10/17/2010

Example of what I have:

Author    Date
Adam      10/10/2011
Adam      12/20/2011
Adam      12/29/2011
Ben       11/14/2011
Curt      10/17/2010
like image 443
ubiquibacon Avatar asked Dec 29 '11 20:12

ubiquibacon


People also ask

How do I undo a sorted list?

In order to reverse the original order of a list, you can use the reverse() method. The reverse() method is used to reverse the sequence of the list and not to arrange it in a sorted order like the sort() method. reverse() method reverses the sequence of the list permanently.

How do you reverse sort a set?

To sort TreeSet in descending order, use the descendingSet() method in Java. The descendingSet() method is used to return a reverse order view of the elements contained in this set.

How do I sort a map in groovy?

Maps don't have an order for the elements, but we may want to sort the entries in the map. Since Groovy 1.7. 2 we can use the sort() method which uses the natural ordering of the keys to sort the entries. Or we can pass a Comparator to the sort() method to define our own sorting algorithm for the keys.


1 Answers

For multi-property sorts like this you'll get the most control if you use the sort() with a closure or a Comparator, e.g.:

sortedList.sort { a, b ->
    if (a.author == b.author) {
        // if the authors are the same, sort by date descending
        return b.date <=> a.date
    }

    // otherwise sort by authors ascending
    return a.author <=> b.author
}

Or a more concise version (courtesy of Ted Naleid):

sortedList.sort { a, b ->

    // a.author <=> b.author will result in a falsy zero value if equal,
    // causing the date comparison in the else of the elvis expression
    // to be returned

    a.author <=> b.author ?: b.date <=> a.date
}

I ran the above in groovysh on the following list:

[
    [author: 'abc', date: new Date() + 1],
    [author: 'abc', date: new Date()],
    [author: 'bcd', date: new Date()],
    [author: 'abc', date: new Date() - 10]
]

And received the correctly sorted:

[
    {author=abc, date=Fri Dec 30 14:38:38 CST 2011},
    {author=abc, date=Thu Dec 29 14:38:38 CST 2011},
    {author=abc, date=Mon Dec 19 14:38:38 CST 2011},
    {author=bcd, date=Thu Dec 29 14:38:38 CST 2011}
]
like image 135
Rob Hruska Avatar answered Sep 18 '22 16:09

Rob Hruska