Sorting 科特林分拣

Sorting 科特林分拣,sorting,kotlin,comparator,comparable,Sorting,Kotlin,Comparator,Comparable,我对Kotlin中的对象排序有问题。我有课 Home(id:String,name:String) 我想先按名称排序,然后按ID排序,其中ID可以是: 像1,2,3,10这样的数字 带字符串的数字:1a,10-14 此解决方案无法提供正确的结果。请不要认为ID是字符串,所以我得到的结果是->1,10,2,3 myList=myList?.sortedWith(通过{it.name}比较,然后通过{it.id})排序) 那么如何通过正确的比较器添加,或者应该如何排序 问候 @编辑 我找到了一个

我对Kotlin中的对象排序有问题。我有课

Home(id:String,name:String)

我想先按名称排序,然后按ID排序,其中ID可以是:

  • 像1,2,3,10这样的数字
  • 带字符串的数字:1a,10-14
此解决方案无法提供正确的结果。请不要认为ID是字符串,所以我得到的结果是
->1,10,2,3

myList=myList?.sortedWith(通过{it.name}比较,然后通过{it.id})排序)

那么如何通过正确的比较器添加
,或者应该如何排序

问候

@编辑 我找到了一个解决方案,但是如何在
中添加它呢

    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)
        }
    })
Collections.sort(字符串,对象:Comparator{
覆盖乐趣比较(o1:String,o2:String):Int{
返回extractInt(o1)-extractInt(o2)
}
趣味提取器Int(s:String):Int{
val num=s.replace(“\\D.toRegex(),”)
//如果找不到数字,则返回0
返回if(num.isEmpty())0 else Integer.parseInt(num)
}
})

您可以使用对象声明扩展可比较接口,并将逻辑放在其中以比较两个字符串,这样您就可以在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)
    }
}
val myList=myList?.sortedWith(compareBy{it.name}.thenBy{
对象:可比{
覆盖有趣的比较对象(其他:字符串):Int{
返回extractInt(it.id)-extractInt(其他)
}
趣味提取器Int(s:String):Int{
val num=s.replace(“\\D.toRegex(),”)
//如果找不到数字,则返回0
返回if(num.isEmpty())0 else Integer.parseInt(num)
}
}

})

它将是
。然后由{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)
}
通过{it.name}进行比较。然后通过{
val num=it.id.replace(“\\D.toRegex(),”)
//如果找不到数字,则返回0
if(num.isEmpty())0 else Integer.parseInt(num)
}
当然,这些解决方案将考虑例如“代码>10 < /代码>和<代码> 10a < /代码>或<代码>为< /代码>和<代码> 0 <代码>相等;这真的是你想要的吗?否则,可以返回一对提取的整数部分和剩余字符串

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)
只是


我想把它们按顺序排列:
1、1a、1f、2d、2j、2-10、3、4、,12
谢谢:)也许你知道如何用正则表达式添加一个id,比如
2-10
,然后把它放在
2和2aaa之间?
?谢谢:)也许你知道如何用正则表达式添加一个id,比如2-10,然后把它放在2和2aaa之间?@CallMePedro创建一个单独的问题
myList?.sortedWith(compareBy({ it.name }, { extractInt(it.id) }))