Ce face Iterable.fold
fold ține o valoare numită de obicei acumulator (acc). Începe cu valoarea initial, apoi pentru fiecare element calculează un acumulator nou din cel vechi și din element. La final întoarce acumulatorul.
Spre deosebire de reduce, fold merge și pe o colecție goală (întoarce initial), iar rezultatul poate avea alt tip decât elementele: poți „strânge” o listă de numere într-un text sau într-un map.
foldIndexed primește în plus poziția elementului, ca prim parametru al lambdei.
Parametri
| Parametru | Descriere |
|---|---|
initial |
Valoarea de pornire a acumulatorului; este și rezultatul pentru o colecție goală. |
operatie |
Primește acumulatorul curent și elementul (plus indexul la foldIndexed) și întoarce acumulatorul nou. |
Ce returnează
Valoarea finală a acumulatorului, de tipul lui initial.
Exemple
Exemplul 1: Soldul unui cont
Pornim de la soldul inițial de 500 de lei și aplicăm fiecare tranzacție (pozitivă = depunere, negativă = plată).
fun main() {
val tranzactii = listOf(1200, -350, -80, 400, -900)
val sold = tranzactii.fold(500) { acc, suma -> acc + suma }
println("Sold final: $sold lei")
val fara = emptyList<Int>()
println("Fără tranzacții: ${fara.fold(500) { acc, suma -> acc + suma }} lei")
}
Rezultat
Sold final: 770 lei
Fără tranzacții: 500 lei
Exemplul 2: Rezultat de alt tip decât elementele
Elementele sunt texte, dar acumulatorul este un Int (numărul de vocale). Apoi construim un text pornind de la un text gol.
fun main() {
val cuvinte = listOf("mere", "pere", "prune")
val vocale = cuvinte.fold(0) { acc, cuv -> acc + cuv.count { it in "aeiouăâî" } }
println("Vocale: $vocale")
val initiale = cuvinte.fold("") { acc, cuv -> acc + cuv.first().uppercaseChar() }
println("Inițiale: $initiale")
}
Rezultat
Vocale: 6
Inițiale: MPP
Exemplul 3: foldIndexed: puncte după poziție
La un concurs, întrebarea de pe poziția i valorează i + 1 puncte. Adunăm doar punctele răspunsurilor corecte.
fun main() {
val raspunsuri = listOf(true, false, true, true)
val puncte = raspunsuri.foldIndexed(0) { i, acc, corect ->
if (corect) acc + (i + 1) else acc
}
println("Punctaj: $puncte din 10")
}
Rezultat
Punctaj: 8 din 10
Greșeli frecvente
- Inversezi parametrii lambdei: la
foldprimul este acumulatorul, al doilea elementul. LafoldIndexedordinea este index, acumulator, element. - Folosești
foldpentru o simplă sumă:sum()sausumOfsunt mai clare.
Comenzi înrudite
Iterable.reduce: Combină elementele pe rând, pornind de la primul element; nu primește valoare inițială.Iterable.runningFold: Ca fold, dar întoarce lista cu toate valorile intermediare ale acumulatorului, de exemplu totalurile parțiale.Iterable.sumOf: Adună valoarea calculată de o funcție pentru fiecare element, de exemplu prețul fiecărui produs din coș.Iterable.joinToString: Lipește elementele într-un singur text, cu separatorul ales, prefix, sufix și, opțional, o transformare.