我在Kotlin中对对象进行排序时遇到问题。我有课
Home(id : String, name : String)
而且我想先按名称排序,然后按ID排序,其中ID可以是:
此解决方案无法提供正确的结果。请不要因为id是String,所以我得到的结果是-> 1, 10, 2, 3
myList = myList?.sortedWith(compareBy<Home> { it.name }.thenBy { it.id })
如何在then.by
中添加正确的比较器,或者应该如何对其进行排序?
问候
@ EDIT我找到了解决方案,但是如何在thenBy
中添加它?
Collections.sort(strings, object : Comparator<String> {
override fun compare(o1: String, o2: String): Int {
return extractInt(o1) - extractInt(o2)
}
fun extractInt(s: String): Int {
val num = s.replace("\\D".toRegex(), "")
// return 0 if no digits found
return if (num.isEmpty()) 0 else Integer.parseInt(num)
}
})
data class Person(
val name: String,
var id: String
)
fun sortPersonsWithParsedIds() {
val p1 = Person("abc", "2")
val p2 = Person("abc", "1")
val p3 = Person("xyz", "10kafsd")
val p4 = Person("xyz", "1asda")
val p5 = Person("pqr", "2aaa")
val p6 = Person("pqr", "20")
val p7 = Person("pqr", "20aa")
val list = listOf(p1, p2, p3, p4, p5, p6, p7)
val sortedList = list.sortedWith(compareBy({ it.name }, { v -> extractInt(v.id) }))
sortedList.forEach { println(it) }
}
private fun extractInt(s: String): Int {
val num = s.replace("\\D".toRegex(), "")
// return 0 if no digits found
return if (num.isEmpty()) 0 else Integer.parseInt(num)
}
结果:
Person(name=abc, id=1)
Person(name=abc, id=2)
Person(name=pqr, id=2aaa)
Person(name=pqr, id=20)
Person(name=pqr, id=20aa)
Person(name=xyz, id=1asda)
Person(name=xyz, id=10kafsd)
只是
myList?.sortedWith(compareBy({ it.name }, { extractInt(it.id) }))
它将是.thenBy { extractInt(it.id) }
(在此处分别声明extractInt
)。或者,如果仅是extractInt
的定义,则在那里输入它:
compareBy<Home> { it.name }.thenBy {
val num = it.id.replace("\\D".toRegex(), "")
// return 0 if no digits found
if (num.isEmpty()) 0 else Integer.parseInt(num)
}
当然,这些解决方案将考虑10
和10a
或as
和0
相等;那真的是你想要的吗?如果没有,则可以返回一对提取的整数部分和剩余的字符串。
您可以使用对象声明来扩展可比较的接口,并在其中放置比较两个字符串的逻辑,这样您就可以在thenBy子句中使用它:
val myList= myList?.sortedWith(compareBy<Home> { it.name }.thenBy {
object: Comparable<String>{
override fun compareTo(other: String): Int {
return extractInt(it.id) - extractInt(other)
}
fun extractInt(s: String): Int {
val num = s.replace("\\D".toRegex(), "")
// return 0 if no digits found
return if (num.isEmpty()) 0 else Integer.parseInt(num)
}
}
})