Kotlin - ArrayList 的自定义排序
Posted
技术标签:
【中文标题】Kotlin - ArrayList 的自定义排序【英文标题】:Kotlin - custom sorting of ArrayList 【发布时间】:2021-12-05 09:39:55 【问题描述】:我正在构建一个 android 应用程序,我想在其中实现 User
的自定义排序
让我详细解释一下要求。
假设有 15 个用户存储在 ArrayList
类型的 User
中,每个用户都有单独的角色映射。用户必须是grouped by roles
,顺序相同as below
。
1.Mechanic
2.Plumber
3.Electrician
此外,在角色组内应主要根据unread message count
排序,其次根据alphabetical order
排序
案例 1:没有未读消息
基于role-based grouping
和alphabetical 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
))
这主要根据未读消息数对列表进行排序,其次根据字母顺序但无法以上述方式完成。
【问题讨论】:
您可能必须先使用groupBy 来对它们进行分组。 @MartinMarconcini 如何完成?请帮帮我。首先它应该显示是否有机械师,然后是电工,然后是管道工。 【参考方案1】:你实际上走的是正确的方向。您只需要另外按角色排序。像这样的:
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
【讨论】:
谢谢。当然,让我试试这个并尽快回来。 我试过了。基于字母顺序和聊天计数的排序工作正常,但分组没有发生:-(请帮帮我。 没有分组是什么意思?排序时忽略角色,所以它们在结果列表中混在一起? 是的。我刚刚试过 this.val rolesOrder = mapOf("Mechanic" to 1, "Plumber" to 2, "Electrician" to 3) users.sortedWith( compareBy我相信 Broot 的回答很好;如果您需要一个“工作示例”,我相信有更聪明/更好/更多的 kotlin 方法,但为什么不从简单开始。
在 5 分钟内,您可以想出一个运行 in the kotlin playground 的示例。
基本上:
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)]
【讨论】:
以上是关于Kotlin - ArrayList 的自定义排序的主要内容,如果未能解决你的问题,请参考以下文章