Clasificación de cadenas por carácter y longitud

En mi aplicación de Android, estoy tratando de clasificar las tags de ruta de bus en order 1, 2, 3..etc.

Para eso estoy usando esto

Collections.sort(directions, Comparator { lhs, rhs -> var obj1 = lhs.short_names.firstOrNull() ?: "" var obj2 = rhs.short_names.firstOrNull() ?: "" if (obj1 === obj2) { obj1 = lhs.headsigns.firstOrNull() ?: "" obj2 = rhs.headsigns.firstOrNull() ?: "" if (obj1 === obj2) { return@Comparator 0 } obj1.compareTo(obj2) } else { obj1.compareTo(obj2) } 

El problema que estoy teniendo es que esto los soluciona, pero se encontrará con el problema de 1, 2, 3, 30, 31, 4, 5

¿Cómo debo cambiar esto para get el order correcto?

Si necesita una simple comparación numérica, puede hacerlo así.

 directions.sortWith(Comparator { lhs, rhs -> val i1 = lhs.toInt() val i2 = rhs.toInt() when { i1 < i2 -> -1 i1 > i2 -> 1 else -> 0 } }) 

Como señaló la tecla de acceso directo, el código anterior puede replacese con una implementación casi idéntica que parece mucho más simple.

 directions.sortBy { it.toInt() } 

La versión general de este algorithm se denomina sorting alfanumérica y se describe en detalle aquí . Hice un puerto Kotlin de este algorithm, que puedes usar. Es más complicado de lo que necesita, pero resolverá su problema.

 class AlphanumComparator : Comparator<String> { override fun compare(s1: String, s2: String): Int { var thisMarker = 0 var thatMarker = 0 val s1Length = s1.length val s2Length = s2.length while (thisMarker < s1Length && thatMarker < s2Length) { val thisChunk = getChunk(s1, s1Length, thisMarker) thisMarker += thisChunk.length val thatChunk = getChunk(s2, s2Length, thatMarker) thatMarker += thatChunk.length // If both chunks contain numeric characters, sort them numerically. var result: Int if (isDigit(thisChunk[0]) && isDigit(thatChunk[0])) { // Simple chunk comparison by length. val thisChunkLength = thisChunk.length result = thisChunkLength - thatChunk.length // If equal, the first different number counts. if (result == 0) { for (i in 0..thisChunkLength - 1) { result = thisChunk[i] - thatChunk[i] if (result != 0) { return result } } } } else { result = thisChunk.compareTo(thatChunk) } if (result != 0) { return result } } return s1Length - s2Length } private fun getChunk(string: String, length: Int, marker: Int): String { var current = marker val chunk = StringBuilder() var c = string[current] chunk.append(c) current++ if (isDigit(c)) { while (current < length) { c = string[current] if (!isDigit(c)) { break } chunk.append(c) current++ } } else { while (current < length) { c = string[current] if (isDigit(c)) { break } chunk.append(c) current++ } } return chunk.toString() } private fun isDigit(ch: Char): Boolean { return '0' <= ch && ch <= '9' } } 

Para usar este Comparator simplemente llame

 directions.sortWith(AlphanumComparator()) 

Si no necesita que se codifique en Kotlin, puede tomar una versión original de Java en la página de Dave Koelle . Y la versión de Kotlin del algorithm también se puede encontrar en GitHub .