Iterable.sortedBy în Kotlin

Sortează elementele după valoarea calculată de o funcție, de exemplu elevii după medie sau orașele după populație.

Sintaxă
fun <T, R : Comparable<R>> Iterable<T>.sortedBy(selector: (T) -> R?): List<T>
fun <T, R : Comparable<R>> Iterable<T>.sortedByDescending(selector: (T) -> R?): List<T>

Ce face Iterable.sortedBy

sortedBy { ... } calculează pentru fiecare element o cheie (un câmp, o lungime) și întoarce o listă nouă cu elementele ordonate crescător după acea cheie. sortedByDescending ordonează descrescător.

Cheia poate fi și null: valorile null ajung primele la sortedBy și ultimele la sortedByDescending. Sortarea este stabilă, deci elementele cu aceeași cheie rămân în ordinea inițială.

Pentru a sorta după două criterii (întâi clasa, apoi numele) folosește sortedWith(compareBy(...)).

Parametri

Parametru Descriere
selector Funcția care dă cheia de sortare pentru fiecare element.

Ce returnează

O List<T> nouă cu elementele sortate.

Exemple

Exemplul 1: Orașe după populație

sortedByDescending pune cel mai mare oraș primul. Elementele sunt perechi, iar it.second este populația.

fun main() {
    val orase = listOf("Iași" to 271_000, "Cluj-Napoca" to 286_000, "Timișoara" to 250_000, "Brașov" to 237_000)
    for ((oras, locuitori) in orase.sortedByDescending { it.second }) {
        println("$oras: $locuitori")
    }
}

Rezultat

Cluj-Napoca: 286000
Iași: 271000
Timișoara: 250000
Brașov: 237000

Exemplul 2: Elevi după medie, crescător

Sortăm obiectele după câmpul medie. Ana și Ion au aceeași medie și rămân în ordinea din listă (sortare stabilă).

data class Elev(val nume: String, val medie: Double)

fun main() {
    val elevi = listOf(Elev("Maria", 9.5), Elev("Ana", 8.0), Elev("Radu", 7.25), Elev("Ion", 8.0))
    elevi.sortedBy { it.medie }.forEach { println("${it.nume} ${it.medie}") }
}

Rezultat

Radu 7.25
Ana 8.0
Ion 8.0
Maria 9.5

Exemplul 3: Cuvinte după lungime

Cheia este lungimea textului. Cuvintele de aceeași lungime își păstrează ordinea.

fun main() {
    val cuvinte = listOf("brad", "ac", "pădure", "tei", "frunză")
    println(cuvinte.sortedBy { it.length })
}

Rezultat

[ac, tei, brad, pădure, frunză]

Greșeli frecvente

  • Pentru două criterii scrii sortedBy { it.clasa }.sortedBy { it.nume }: a doua sortare decide ordinea finală, deci rezultatul e sortat după nume, nu după clasă. Folosește sortedWith(compareBy({ it.clasa }, { it.nume })).
  • Aștepți ca lista originală să se schimbe. Pentru sortare pe loc folosește sortBy pe o MutableList.

Comenzi înrudite

  • Iterable.sorted: Întoarce o listă nouă cu elementele în ordine crescătoare (sorted) sau descrescătoare (sortedDescending).
  • Iterable.sortedWith: Sortează după un Comparator: mai multe criterii cu compareBy/thenBy sau ordine românească cu Collator.
  • compareBy: Creează un Comparator care compară obiectele după una sau mai multe proprietăți, în ordine; se folosește cu sortedWith.
  • MutableList.sort: Sortează chiar lista modificabilă (pe loc), crescător, descrescător sau după un câmp; nu întoarce nimic.
  • Iterable.maxBy: Întoarce elementul pentru care funcția dată are valoarea cea mai mare (maxBy) sau cea mai mică (minBy).