In my Android app, I have a list of a Custom object having the following fields,
var myNotesList: ArrayList<Note>
class Note(
var title: String
var date: String,
var status: String)
Here the status
can be any of the following three values:
Draft, Pending, Completed
Now, I want my list to be ordered in the fashion where Drafts are first and sorted in descending order of date, then Pending sorted with the date then Completed status items.
for example,
{someNoteTitle, draft, 07 Jan 2021},
{someNoteTitle, draft, 06 Jan 2021},
{someNoteTitle, draft, 04 Jan 2021},
{someNoteTitle, Pending, 07 Jan 2021},
{someNoteTitle, Pending, 06 Jan 2021},
{someNoteTitle, Completed, 07 Jan 2021},
{someNoteTitle, Completed, 05 Jan 2021},
{someNoteTitle, Completed, 02 Jan 2021}
I have tried with the sortedWith
and compareBy
but due to the status order requirement is not alphabetical, I am not getting a way to do this with in-built functions, or else I will have to do it in a dirty way with loops.
I don't see a way without doing some dirty comparators to sort your array, like this for the status (and for the date it would be way dirtier) :
myNotesList.sortedWith(object: Comparator<String> {
override fun compare(a: String, b: String): Int {
return when {
a == "DRAFT" && b == "PENDING" -> -1
a == "DRAFT" && b == "COMPLETED" -> -1
a == "PENDING" && b == "DRAFT" -> 1
a == "PENDING" && b == "COMPLETED" -> -1
a == "COMPLETED" && b == "PENDING" -> 1
a == "COMPLETED" && b == "DRAFT" -> 1
else -> 0
}
}
})
What I would do is change the Note object by using types that can be ordered the way I want. If you cannot change the Note object, i would create another object and create a mapper to map the Note to the new type.
For instance, first i would create an object for the status of the note with an enum (but you'll have to be careful as the order will be tied the enum item order which can sometimes cause issues)
enum class Status {
DRAFT,
PENDING,
COMPLETED
}
For the date I would use a Date object, LocalDate for example. Once again it is your mapper (if you cannot change the Note object) that will allow you to transform the String date to a LocalDate object.
So your final object would look like :
class Note(
var title: String,
var date: LocalDate,
var status: Status)
Then you can simply do :
myNotesList.sortedWith(compareBy<Note>({it.status}).thenByDescending({it.date})))