ubiquibacon
ubiquibacon

Reputation: 10667

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

Upvotes: 9

Views: 13609

Answers (1)

Rob Hruska
Rob Hruska

Reputation: 120286

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}
]

Upvotes: 21

Related Questions