Сортировка строк по символу и длине

В моем приложении для Android я пытаюсь сортировать теги маршрута автобуса в порядке 1, 2, 3..etc.

Для этого я использую это

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

Проблема, с которой я сталкиваюсь, – это их сортировка, но она столкнется с проблемой 1, 2, 3, 30, 31, 4, 5

Как мне изменить это, чтобы получить правильный порядок.

Если вам нужно просто простое сравнение чисел, вы можете сделать это так.

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

Как указывала горячая клавиша , код выше может быть заменен почти идентичной реализацией, которая выглядит намного проще.

 directions.sortBy { it.toInt() } 

Общая версия этого алгоритма называется сортировкой по алфавиту и подробно описана здесь . Я сделал порт Котлин этого алгоритма, который вы можете использовать. Это сложнее, чем вам нужно, но это решит вашу проблему.

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

Чтобы использовать этот Comparator просто позвоните

 directions.sortWith(AlphanumComparator()) 

Если вам не нужно, чтобы он был закодирован в Котлине, вы можете просто взять оригинальную версию Java на странице Дейва Коэля . И алгоритм Kotlin алгоритма можно также найти на GitHub .

Intereting Posts
Атрибут Button onClick не имеет значения, если активность написана в Котлине Как я могу передать правильную ссылку на метод, чтобы Nashorn мог ее выполнить? Как проверить, что строка не равна строке, тогда она будет работать иначе? в котлин Как изменить порядок сравнения в Kotlin Обновите содержимое фрагмента в разделе PagerAdapter Kotlin и Jack не поддерживаются (Android Studio 2.3.2) Межстраничные объявления Admob: «IllegalStateException: только действия в полноэкранном режиме могут запрашивать ориентацию» Невозможно найти сеттер для поля – используя базу данных Kotlin с комнатой Как организовать файлы ресурсов макета в Android Studio? Игнорировать setter и установить свойство напрямую Удалить символы из строки, которая встречается в другой строке в Котлине Kotlin: «если элемент не в списке» правильный синтаксис Тип-Безопасность с необязательными полями в классе данных для JSON Тесты Kotlin и android lint В android kotlin, используя библиотеку степпера, передавая пользовательские значения переключателей по нескольким фрагментам, которые будут использоваться на сводной странице