Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
343 views
in Technique[技术] by (71.8m points)

android - How can I reorder or sort a list based on two fields not having any alphabetical or numerical order in Kotlin?

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...