我正在构建一个Android应用程序,我想实现User
的自定义排序
让我详细解释一下这个要求。
假设有15个用户存储在User
类型的ArrayList
中,每个用户都有单独的角色映射。
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
}))
}
这主要基于未读消息计数,其次基于字母顺序排序列表,但无法以上述方式完成。
你其实走对了方向。您只需要按角色进行额外排序。像这样:
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)]