Iterable.distinct în Kotlin

Elimină duplicatele și întoarce o listă cu fiecare element o singură dată, în ordinea primei apariții.

Sintaxă
fun <T> Iterable<T>.distinct(): List<T>
fun <T, K> Iterable<T>.distinctBy(selector: (T) -> K): List<T>

Ce face Iterable.distinct

distinct() întoarce o listă nouă în care fiecare valoare apare o singură dată. Se păstrează prima apariție și ordinea originală. Două elemente sunt considerate egale după equals (pentru data class, după toate câmpurile).

distinctBy { ... } compară elementele după o cheie: de exemplu un elev pe oraș sau un cuvânt indiferent de majuscule. Din fiecare grup cu aceeași cheie rămâne primul element.

Dacă nu te interesează ordinea și vrei o mulțime, toSet() face același lucru și întoarce un Set.

Parametri

Parametru Descriere
selector Doar la distinctBy: funcția care dă cheia după care se compară elementele.

Ce returnează

O List<T> fără duplicate.

Exemple

Exemplul 1: Orașele vizitate, fără repetări

Lista are orașe repetate; distinct păstrează prima apariție a fiecăruia, în ordinea originală.

fun main() {
    val excursii = listOf("Sibiu", "Iași", "Sibiu", "Cluj", "Iași", "Sibiu")
    val orase = excursii.distinct()
    println(orase)
    println("Orașe diferite: ${orase.size}")
}

Rezultat

[Sibiu, Iași, Cluj]
Orașe diferite: 3

Exemplul 2: distinctBy: câte un elev din fiecare oraș

Cheia este orașul, deci rămâne primul elev din fiecare oraș.

data class Elev(val nume: String, val oras: String)

fun main() {
    val elevi = listOf(
        Elev("Ana", "Iași"), Elev("Ion", "Cluj"),
        Elev("Maria", "Iași"), Elev("Radu", "Brașov"), Elev("Dan", "Cluj"),
    )
    elevi.distinctBy { it.oras }.forEach { println("${it.oras}: ${it.nume}") }
}

Rezultat

Iași: Ana
Cluj: Ion
Brașov: Radu

Exemplul 3: Fără să ținem cont de majuscule

distinct consideră „Mere” și „mere” diferite. Cu distinctBy { it.lowercase() } rămâne doar prima formă.

fun main() {
    val etichete = listOf("Mere", "pere", "mere", "PERE", "prune")
    println(etichete.distinct())
    println(etichete.distinctBy { it.lowercase() })
}

Rezultat

[Mere, pere, mere, PERE, prune]
[Mere, pere, prune]

Greșeli frecvente

  • Folosești distinct pe obiecte dintr-o clasă obișnuită (nu data class): fiecare obiect este diferit de celelalte, chiar cu aceleași câmpuri. Folosește data class sau distinctBy.
  • Scrii toSet().toList() pentru a elimina duplicatele: merge, dar distinct() spune mai clar ce vrei.

Comenzi înrudite

  • Iterable.toSet: Transformă colecția într-o mulțime (fără duplicate): toSet, toMutableSet sau toSortedSet (sortată).
  • Iterable.groupBy: Împarte elementele în grupe după o cheie și întoarce un map: cheie → lista elementelor din acea grupă.
  • Iterable.union: Operații pe mulțimi: union (reuniunea), intersect (elementele comune) și subtract (diferența); rezultatul e un Set.
  • setOf: Creează o mulțime: o colecție fără duplicate, în care verifici rapid dacă un element există.
  • Iterable.count: Numără elementele colecției sau doar pe cele care îndeplinesc o condiție.