Kotlin -自定义数组列表排序



我正在构建一个Android应用程序,我想实现User的自定义排序

让我详细解释一下这个要求。

假设有15个用户存储在User类型的ArrayList中,每个用户都有单独的角色映射。

用户必须为grouped by roles,且顺序与as below相同。
1.Mechanic 
2.Plumber 
3.Electrician

同样,角色组中的它们应该首先基于unread message count,其次基于alphabetical order

进行排序。案例1:没有未读消息

基于role-based groupingalphabetical sorting(不含未读消息),用户显示方式如下:(括号中的"0"表示未读消息数)

Aarav,Mechanic(0)
Dhruv,Mechanic(0)
Jason,Mechanic(0)
Pranav,Mechanic(0)
Zeplin,Mechanic(0)
Amit,Plumber(0)
Baskaran,Plumber(0)
Garry,Plumber(0)
Rakesh,Plumber(0)
Shekar,Plumber(0)
Balu,Electrician(0)
Ragunathan,Electrician(0)
Prem kumar,Electrician(0)
Saravanan,Electrician(0)
Thanigaivel,Electrician(0)

案例2:未读消息计数

当有用户(在角色中)有未读聊天计数时,列表应该优先考虑他们,字母顺序应该被认为是次要的。它通常看起来像下面这样:

Zeplin,Mechanic(20)
Pranav,Mechanic(10)
Aarav,Mechanic(0)
Dhruv,Mechanic(0)
Jason,Mechanic(0)
Garry,Plumber(5)
Rakesh,Plumber(5)
Amit,Plumber(0)
Baskaran,Plumber(0)
Shekar,Plumber(0)
Prem kumar,Electrician(10)
Balu,Electrician(0)
Ragunathan,Electrician(0)
Saravanan,Electrician(0)
Thanigaivel,Electrician(0)

请帮我完成这件事。

下面是我尝试过的

fun getListWithGroupingAndSorting(){
val users = ArrayList<User>
// Writing logic to pull list of users from server and assigning to `users`
return ArrayList(users.sortedWith(compareByDescending<User> {
it.unreadMessageCount
}.thenBy {
it.firstName
}))

}

这主要基于未读消息计数,其次基于字母顺序排序列表,但无法以上述方式完成。

你其实走对了方向。您只需要按角色进行额外排序。像这样:

val rolesOrder = mapOf("Mechanic" to 1, "Plumber" to 2, "Electrician" to 3)
users.sortedWith(
compareBy<User> { rolesOrder[it.role] }
.thenByDescending { it.unreadMessageCount }
.thenBy { it.firstName }
)

如果你真的需要对项目进行分组而不仅仅是排序,那么你需要像Map<Role, List<Users>>这样的东西,然后:

users.groupByTo(sortedMapOf(compareBy { rolesOrder[it] })) { it.role }
.mapValues { (_, value) ->
value.sortedWith(
compareByDescending<User> { it.unreadMessageCount }
.thenBy { it.firstName }
)
}

如果你有一个有序的角色列表,你需要为它们分配索引,你可以这样做:

val rolesOrder = listOf("Mechanic", "Plumber", "Electrician")
.withIndex()
.associate { it.value to it.index }

注意,如果rolesOrder中缺少角色,则用户将被放在开头。如果这是一种可能的情况,并且您希望将它们放在末尾,那么像这样比较角色:

rolesOrder[it.role] ?: Integer.MAX_VALUE

我相信Broot的回答很好;如果你需要一个"有效的例子",我相信有更聪明/更好/更多的方法,但为什么不从简单的开始呢?

在5分钟内,你可以想出一个在kotlin操场上运行的例子。

基本上:

data class User(val role: String, val unread: Int = 0)
fun main() {
val unsorted = listOf(User("Mechanic", 5), 
User("Plumber", 3),
User("Electrician", 2),
User("Mechanic", 9),
User("Mechanic", 1),
User("Electrician", 8),
User("Mechanic", 4),
User("Plumber", 0))

// Group them
val sortedByRole = unsorted
.groupBy { it.role }
.forEach { k, group ->  
val sortedGroup = group.sortedByDescending { user -> user.unread }
println(sortedGroup)
} 
}

输出:

[User(role=Mechanic, unread=9), User(role=Mechanic, unread=5), User(role=Mechanic, unread=4), User(role=Mechanic, unread=1)]
[User(role=Plumber, unread=3), User(role=Plumber, unread=0)]
[User(role=Electrician, unread=8), User(role=Electrician, unread=2)]