在 kotlin 中对包含数字的字符串进行排序

Meh*_*hah 3 collections android kotlin mutablelist

我想对一些包含数字的字符串进行排序,但经过排序后,它变成了这样["s1", "s10", "s11", ... ,"s2", "s21", "s22"]。在我搜索后,我发现这个问题有同样的问题。但是在我的示例中,我有mutableList<myModel>,并且我必须将所有字符串放入myModel.title例如可变列表中并放入代码下:

   val sortData = reversedData.sortedBy {
          //pattern.matcher(it.title).matches()
             Collections.sort(it.title, 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)
                 }
            })
        }
Run Code Online (Sandbox Code Playgroud)

我在.sortedBy和 中有错误Collections.sort(it.title),请帮我解决这个问题。

hak*_*kim 5

您可以使用sortWith代替 sortBy 例如:

class Test(val title:String) {
  override fun toString(): String {
    return "$title"
  }
}

val list = listOf<Test>(Test("s1"), Test("s101"),
Test("s131"), Test("s321"), Test("s23"), Test("s21"), Test("s22"))
val sortData = list.sortedWith( object : Comparator<Test> {
override fun compare(o1: Test, o2: Test): Int {
    return extractInt(o1) - extractInt(o2)
}

fun extractInt(s: Test): Int {
    val num = s.title.replace("\\D".toRegex(), "")
    // return 0 if no digits found
    return if (num.isEmpty()) 0 else Integer.parseInt(num)
}
Run Code Online (Sandbox Code Playgroud)

})

将给出输出: [s1, s21, s22, s23, s101, s131, s321]


小智 2

一个可能的解决方案可以是这样的:

  reversedData.toObservable()
                    .sorted { o1, o2 ->
                        val pattern = Pattern.compile("\\d+")
                        val matcher = pattern.matcher(o1.title)
                        val matcher2 = pattern.matcher(o2.title)

                        if (matcher.find()) {
                            matcher2.find()
                            val o1Num = matcher.group(0).toInt()
                            val o2Num = matcher2.group(0).toInt()

                            return@sorted o1Num - o2Num
                        } else {
                            return@sorted o1.title?.compareTo(o2.title ?: "") ?: 0
                        }
                    }
                    .toList()
                    .subscribeBy(
                        onError = {
                            it
                        },
                        onSuccess = {
                            reversedData = it
                        }
                    )
Run Code Online (Sandbox Code Playgroud)