首页 文章

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

提问于
浏览
0

我想排序一些包含数字的字符串,但经过排序后,它变得像 ["s1", "s10", "s11", ... ,"s2", "s21", "s22"] . 在我搜索之后我将这个question同样的问题 . 但在我的例子中,我有 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)
                 }
            })
        }

我在 .sortedByCollections.sort(it.title) 有错误,请帮我解决这个问题 .

4 回答

  • 0

    基于您发布的数据的可能解决方案:

    sortedBy { "s(\\d+)".toRegex().matchEntire(it)?.groups?.get(1)?.value?.toInt() }
    

    当然我会把正则表达式从lambda中移出来,但这是一个更简洁的答案 .

  • 0

    您可以使用 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)
    }
    

    })

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

  • 0

    当你声明你需要一个MutableList,但还没有MutableList时,你应该使用sortedBysortedWith(如果你想使用比较器)而你只得到一个(新的)列表,例如:

    val yourMutableSortedList = reversedData.sortedBy {
      pattern.find(it)?.value?.toInt() ?: 0
    }.toMutableList() // now calling toMutableList only because you said you require one... so why don't just sorting it into a new list and returning a mutable list afterwards?
    

    你可能想利用compareBy(或Javas Comparator.comparing )来获得 sortedWith .

    如果您只想对现有的可变列表进行排序,请使用sortWith(或 Collections.sort ):

    reversedData.sortWith(compareBy {
      pattern.find(it)?.value?.toInt() ?: 0
    })
    
    // or using Java imports:
    Collections.sort(reversedData, Compatarator.comparingInt {
      pattern.find(it)?.value?.toInt() ?: 0 // what would be the default for non-matching ones?
    })
    

    当然你也可以玩其他比较器助手(例如混合空值,或类似),例如:

    reversedData.sortWith(nullsLast(compareBy {
      pattern.find(it)?.value
    }))
    

    对于上面的示例,我使用了以下Regex

    val pattern = """\d+""".toRegex()
    
  • 0

    一个可能的解决方案是:

    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
                            }
                        )
    

相关问题