Как отсортировать список
fun main() {
val nums = listOf(5, 2, 9, 1, 7)
println(nums.sorted())
println(nums.sortedDescending())
println(nums)
}[1, 2, 5, 7, 9]
[9, 7, 5, 2, 1]
[5, 2, 9, 1, 7]sorted() и sortedDescending() возвращают новый список, а исходный остаётся как был — это видно по последней строке.
Изменяемый список — на месте
У MutableList есть sort() и sortDescending(): они меняют сам список и ничего не возвращают:
fun main() {
val list = mutableListOf(3, 1, 2)
list.sort()
println(list)
list.sortDescending()
println(list)
}[1, 2, 3]
[3, 2, 1]У списка из listOf функции sort() нет: менять его нельзя, и код не соберётся. Берите sorted() или сделайте изменяемую копию — toMutableList().
По свойству: sortedBy
Сортировать можно не по самим значениям, а по тому, что из них получается. Для строк — по длине или без учёта больших и маленьких букв:
fun main() {
val words = listOf("pear", "apple", "Fig", "banana")
println(words.sorted())
println(words.sortedBy { it.lowercase() })
println(words.sortedBy { it.length })
println(words.sortedByDescending { it.length })
}[Fig, apple, banana, pear]
[apple, banana, Fig, pear]
[Fig, pear, apple, banana]
[banana, apple, pear, Fig]В первой строке Fig встал первым: строки сравниваются по кодам символов, а у всех заглавных латинских букв коды меньше, чем у строчных. Чтобы регистр не мешал, сортируйте по it.lowercase().
Объекты по нескольким полям
data class Student(val name: String, val grade: Int)
fun main() {
val students = listOf(
Student("Oleg", 8),
Student("Anna", 9),
Student("Ivan", 8),
)
val sorted = students.sortedWith(compareByDescending<Student> { it.grade }.thenBy { it.name })
for (s in sorted) {
println("${s.name} ${s.grade}")
}
}Anna 9
Ivan 8
Oleg 8Сначала по оценке по убыванию, при равной оценке — по имени. compareBy — по возрастанию, compareByDescending — по убыванию, thenBy и thenByDescending — следующее поле.
Подводные камни
list.sorted()без присваивания ничего не меняет: результат нужно сохранить —val s = list.sorted().reversed()просто переворачивает порядок, а не сортирует:listOf(2, 3, 1).reversed()—[1, 3, 2].- Сортировка устойчивая: элементы с одинаковым ключом остаются в прежнем порядке относительно друг друга. В примере с учениками без
thenByуOlegиIvan(оба с оценкой 8) сохранился бы исходный порядок: сначалаOleg, потомIvan. - Русские строки сортируются по кодам символов тоже:
ёокажется после всех букв отадоя. Для «словарного» порядка нуженjava.text.Collator.