Глиф Учебники

Как отсортировать список

Справочник · Kotlin · 1 минута чтения

Kotlin
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(): они меняют сам список и ничего не возвращают:

Kotlin
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

Сортировать можно не по самим значениям, а по тому, что из них получается. Для строк — по длине или без учёта больших и маленьких букв:

Kotlin
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().

Объекты по нескольким полям

Kotlin
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 — следующее поле.

Подводные камни