【问题标题】:How can I reorder or sort a list based on two fields not having any alphabetical or numerical order in Kotlin?如何根据 Kotlin 中没有任何字母或数字顺序的两个字段对列表进行重新排序或排序?
【发布时间】:2021-04-13 00:01:02
【问题描述】:

在我的 Android 应用中,我有一个包含以下字段的自定义对象列表,

var myNotesList: ArrayList<Note>

class Note(
     var title: String
     var date: String,
     var status: String)

这里的status 可以是以下三个值中的任何一个:

草稿、待处理、已完成

现在,我希望我的列表以先草稿并按日期降序排序的方式排序,然后按日期排序待处理,然后按已完成状态项排序。

例如,

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

我尝试过使用sortedWithcompareBy,但由于状态顺序要求不是按字母顺序排列的,我无法使用内置函数执行此操作,否则我将不得不在带有循环的肮脏方式。

【问题讨论】:

    标签: android sorting kotlin comparable


    【解决方案1】:

    如果不做一些肮脏的比较器来对你的数组进行排序,我看不到一种方法,比如状态(以及日期会更脏):

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

    我要做的是通过使用可以按我想要的方式排序的类型来更改 Note 对象。如果您无法更改 Note 对象,我将创建另一个对象并创建一个映射器以将 Note 映射到新类型。

    例如,首先我会创建一个带有枚举的笔记状态对象(但您必须小心,因为订单将与枚举项目订单绑定,这有时会导致问题)

    enum class Status {
        DRAFT,
        PENDING,
        COMPLETED
    }
    

    对于日期,我会使用 Date 对象,例如 LocalDate。再次是您的映射器(如果您无法更改 Note 对象)将允许您将字符串日期转换为 LocalDate 对象。

    所以你的最终对象看起来像:

    class Note(
         var title: String,
         var date: LocalDate,
         var status: Status)
    

    那么你可以简单地做:

    myNotesList.sortedWith(compareBy<Note>({it.status}).thenByDescending({it.date})))
    

    【讨论】:

    • 是的,我在考虑这种使用Enum 的方法,@IR42 在对我的问题的评论中也推荐了这种方法。让我尝试一下,因为我需要从 String 更改日期字段类型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-21
    • 1970-01-01
    相关资源
    最近更新 更多