I have a book book list and it contains book id, publisher name, contact number, address, book release date and book status (active, deleted, suspended) . I want to sort a list based on the following criteria:
For example, the result should be:
Activation Date: 18.10.2014
Test Book, ABC publisher, active
Test Book2, ABC publisher, suspended
Book3, XXYYBB publisher, active
Activation Date: 19.10.2014
Test Book5, XXYYBB publisher, deleted
Test Book3, ZZZZ publisher, active
Test Book4, ZZZZ publisher, suspended
My sample code:
booklist.sort{ x,y ->
x.activateDate <=> y.activateDate ?: x.publisherName <=> y.publisherName
}
how to do the third manual check for the book status?
enum
If the status is indeed limited to the three exact values given, you should probably already be using something like this anyway:
enum BookStatus { active, suspended, deleted }
Then in the Book class:
class Book {
...
BookStatus status
}
Since Enum classes already have a natural sort order (order of declaration) you are all set, just add another elvis ( ?:
) clause to your comparator closure:
booklist.sort { x, y ->
x.activateDate <=> y.activateDate ?:
x.publisherName <=> y.publisherName ?:
x.status <=> y.status
}
List
See @cfrick 's solution
Map
There are only a couple of minor advantages of this solution over the List-based solution:
LinkedHashMap
has algorithmic complexity O(1) while average element search through an ArrayList
has O(n) . statusOrder[x.status] <=> statusOrder[y.status]
is a marginally simpler expression than statusList.indexOf(x.status) <=> statusList.indexOf(y.status)
Here Book.status
is assumed to be a String
:
final statusOrder = [ active:0, suspended:1, deleted:2 ].asImmutable()
booklist.sort { x, y ->
x.activateDate <=> y.activateDate ?:
x.publisherName <=> y.publisherName ?:
statusOrder[x.status] <=> statusOrder[y.status]
}
If I were for some reason unable to use the Enum
solution, I would probably use the List
solution unless there were a large (more than 20?) number of status values, in which case I would use the Map
solution.
in case these are strings, you can use a list to define the importance and then use the index in this list with the ufo-operator
final order = ['active','suspended','deleted']
def l = [
[status: 'deleted'],
[status: 'active'],
[status: 'suspended'],
[status: 'active'],
[status: 'suspended'],
]
println l.sort{ a,b -> order.indexOf(a.status) <=> order.indexOf(b.status) }
// -> [[status:active], [status:active], [status:suspended], [status:suspended], [status:deleted]]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.