Ce face generateSequence
generateSequence(inceput) { anterior -> urmator } pornește de la o valoare și calculează următoarea din cea precedentă. Secvența se termină când funcția întoarce null; dacă nu întoarce niciodată null, secvența este infinită.
O secvență infinită nu este o problemă cât timp iei doar o parte din ea: take(10), first { ... }, takeWhile { ... }. Elementele se calculează doar când sunt cerute.
Varianta fără valoare de început apelează funcția de fiecare dată (de exemplu pentru a citi linii până la sfârșit: generateSequence(::readLine)).
Parametri
| Parametru | Descriere |
|---|---|
inceput |
Primul element. Dacă este null, secvența este goală. |
urmator |
Funcția care primește elementul anterior și întoarce următorul, sau null pentru oprire. |
Ce returnează
O Sequence<T> (posibil infinită).
Exemple
Exemplul 1: Economii lunare cu dobândă
Pornim de la 1000 de lei și fiecare lună adaugă 2%. Secvența este infinită, așa că luăm doar primele 6 valori.
fun main() {
val sold = generateSequence(1000.0) { it * 1.02 }
sold.take(6).forEachIndexed { luna, suma ->
println("Luna $luna: ${"%.2f".format(suma)} lei")
}
}
Rezultat
Luna 0: 1000.00 lei
Luna 1: 1020.00 lei
Luna 2: 1040.40 lei
Luna 3: 1061.21 lei
Luna 4: 1082.43 lei
Luna 5: 1104.08 lei
Exemplul 2: Secvență care se oprește singură
Înjumătățim până ajungem la 1; după 1 funcția întoarce null și secvența se termină.
fun main() {
val injumatatiri = generateSequence(100) { if (it > 1) it / 2 else null }
println(injumatatiri.toList())
val putere = generateSequence(1) { it * 2 }.first { it > 1000 }
println("Prima putere a lui 2 peste 1000: $putere")
}
Rezultat
[100, 50, 25, 12, 6, 3, 1]
Prima putere a lui 2 peste 1000: 1024
Exemplul 3: Citirea liniilor până la sfârșit
readlnOrNull întoarce null la sfârșitul intrării, deci secvența se oprește singură.
fun main() {
val linii = generateSequence { readlnOrNull() }
val note = linii.map { it.substringAfter(" ").toInt() }.toList()
println("Note citite: $note, media ${note.average()}")
}
Ce scrie utilizatorul (intrare)
Ana 9
Ion 7
Maria 10
Rezultat
Note citite: [9, 7, 10], media 8.666666666666666
Greșeli frecvente
- Apelezi
toList()saucount()pe o secvență infinită: programul nu se mai termină (sau rămâne fără memorie). Limitează întâi cutakesautakeWhile. - Confunzi valoarea de început cu primul element calculat:
inceputapare și el în secvență.
Comenzi înrudite
sequence: Construiește o secvență dintr-un bloc de cod care dă valori una câte una cu yield; codul se oprește și continuă la cerere.sequenceOf: Creează o secvență: o colecție „leneșă” ale cărei operații se fac element cu element, doar când ceri rezultatul.Iterable.take: take(n) întoarce primele n elemente, iar drop(n) întoarce tot ce rămâne după ce sari peste primele n.Iterable.takeWhile: takeWhile ia elementele de la început cât timp condiția e adevărată; dropWhile le sare și întoarce restul.