Search code examples
androidcollectionskotlinmutablelist

Sorting Strings that contains number in kotlin


I wanna sort some strings that contain numbers but after a sort, it becomes like this ["s1", "s10", "s11", ... ,"s2", "s21", "s22"]. after i search i fount this question with same problem. but in my example, I have mutableList<myModel>, and I must put all string in myModel.title for example into a mutable list and place into under code:

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

I have an error in .sortedBy and Collections.sort(it.title), may please help me to fix this.


Solution

  • A possible solution can be this:

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