Iterable.associateBy în Kotlin

Grupare, împărțire și combinare Kotlin 1.0 (associateWith: 1.3)

associateBy face un map cu elementele ca valori și o cheie calculată; associateWith ține elementele ca chei.

Sintaxă
fun <T, K> Iterable<T>.associateBy(cheie: (T) -> K): Map<K, T>
fun <K, V> Iterable<K>.associateWith(valoare: (K) -> V): Map<K, V>

Ce face Iterable.associateBy

associateBy { it.cod } construiește un map în care valoarea este elementul, iar cheia este calculată de lambda. Este util pentru căutări rapide după un identificator: în loc de find pe toată lista, scrii map[cod].

associateWith { ... } face invers: elementul devine cheia, iar lambda dă valoarea. De exemplu, din lista de cuvinte obții map-ul cuvânt → lungime.

La chei repetate rămâne ultimul element cu acea cheie, la fel ca la associate.

Parametri

Parametru Descriere
cheie La associateBy: funcția care dă cheia pentru fiecare element.
valoare La associateWith: funcția care dă valoarea pentru fiecare element (cheie).

Ce returnează

Un Map care păstrează ordinea elementelor.

Exemple

Exemplul 1: Căutare după cod

Indexăm persoanele după un cod. Căutarea în map este directă, fără să parcurgem lista.

data class Persoana(val cod: String, val nume: String, val oras: String)

fun main() {
    val persoane = listOf(
        Persoana("A12", "Ana Popescu", "Iași"),
        Persoana("B07", "Ion Ionescu", "Cluj"),
        Persoana("C33", "Maria Pop", "Sibiu"),
    )
    val dupaCod = persoane.associateBy { it.cod }
    println(dupaCod["B07"]?.nume)
    println(dupaCod["Z99"]?.nume ?: "Cod necunoscut")
}

Rezultat

Ion Ionescu
Cod necunoscut

Exemplul 2: associateWith: cuvânt → lungime

Cuvintele devin chei, iar valoarea fiecăruia este numărul de litere.

fun main() {
    val cuvinte = listOf("soare", "lună", "stea")
    println(cuvinte.associateWith { it.length })
}

Rezultat

{soare=5, lună=4, stea=4}

Exemplul 3: Inițializarea unui catalog

Pornim de la lista de elevi și dăm fiecăruia o listă goală de note. Rezultatul îl facem modificabil cu toMutableMap().

fun main() {
    val elevi = listOf("Ana", "Ion", "Maria")
    val catalog = elevi.associateWith { mutableListOf<Int>() }.toMutableMap()
    catalog["Ana"]?.add(10)
    catalog["Ion"]?.add(8)
    catalog["Ana"]?.add(9)
    println(catalog)
}

Rezultat

{Ana=[10, 9], Ion=[8], Maria=[]}

Greșeli frecvente

  • Confunzi cele două: la associateBy elementul este valoarea, la associateWith elementul este cheia.
  • Indexezi după un câmp care nu e unic (de exemplu orașul): rămâne doar ultima persoană din fiecare oraș. Pentru toate folosește groupBy.

Comenzi înrudite

  • Iterable.associate: Construiește un map din colecție: pentru fiecare element lambda întoarce o pereche cheie to valoare.
  • Iterable.groupBy: Împarte elementele în grupe după o cheie și întoarce un map: cheie → lista elementelor din acea grupă.
  • Iterable.toMap: Transformă o listă de perechi (cheie to valoare) într-un map; la chei repetate rămâne ultima valoare.
  • Map.getValue: Citește valoarea unei chei: getValue aruncă excepție dacă lipsește, getOrDefault și getOrElse dau o valoare de rezervă.