Ce face Iterable
Iterable<E> descrie o succesiune de elemente de tipul E care pot fi parcurse, în ordine, cu for-in. List, Set, map.keys și map.values sunt toate Iterable, deci au aceleași metode: map, where, fold, join, first și multe altele.
Multe metode (map, where, take, skip) sunt leneșe: nu calculează nimic pe loc, ci returnează un nou Iterable care calculează elementele abia când este parcurs. De aceea print pe un astfel de rezultat afișează elementele între paranteze rotunde, (1, 2, 3), nu între paranteze drepte ca o listă. Apelează toList() când ai nevoie de o listă.
Constructorul Iterable.generate(n, f) creează un iterable cu elementele f(0), f(1), …, f(n - 1); fără funcție, elementele sunt chiar numerele 0 … n – 1. Iterable.empty() creează un iterable fără niciun element.
Parametri
| Parametru | Descriere |
|---|---|
count |
Pentru Iterable.generate: câte elemente are rezultatul. |
generator |
Funcția care primește poziția (0, 1, 2, …) și returnează elementul. Dacă lipsește, elementul este chiar poziția. |
Ce returnează
Un obiect Iterable. Elementele lui se calculează abia când îl parcurgi.
Exemple
Exemplul 1: Același cod pentru listă, mulțime și cheile unui map
Funcția afiseaza primește orice Iterable<String>, deci merge cu o listă, cu un set sau cu cheile unui map.
void afiseaza(String titlu, Iterable<String> elemente) {
print('$titlu (${elemente.length}): ${elemente.join(', ')}');
}
void main() {
final orase = ['Iași', 'Cluj', 'Brașov'];
final culori = {'roșu', 'galben', 'albastru'};
final populatie = {'Iași': 271692, 'Timișoara': 250849};
afiseaza('Listă', orase);
afiseaza('Set', culori);
afiseaza('Chei', populatie.keys);
for (final oras in populatie.keys) {
print('$oras are ${populatie[oras]} locuitori');
}
}
Rezultat
Listă (3): Iași, Cluj, Brașov
Set (3): roșu, galben, albastru
Chei (2): Iași, Timișoara
Iași are 271692 locuitori
Timișoara are 250849 locuitori
Exemplul 2: Iterable.generate și Iterable.empty
Rezultatul lui generate este leneș: print îl afișează cu paranteze rotunde. toList() îl transformă în listă.
void main() {
final pozitii = Iterable<int>.generate(5);
final patrate = Iterable.generate(5, (i) => i * i);
const nimic = Iterable<String>.empty();
print(pozitii);
print(patrate);
print(patrate.toList());
print('gol: $nimic, isEmpty = ${nimic.isEmpty}');
}
Rezultat
(0, 1, 2, 3, 4)
(0, 1, 4, 9, 16)
[0, 1, 4, 9, 16]
gol: (), isEmpty = true
Exemplul 3: Calculul leneș: elementele se calculează la parcurgere
Funcția din map nu rulează când creezi dublate, ci abia în bucla for. Dacă parcurgi de două ori, se calculează de două ori.
void main() {
final note = [7, 9, 10];
final dublate = note.map((n) {
print(' calculez $n');
return n * 2;
});
print('Am creat iterable-ul, nimic calculat încă.');
for (final d in dublate) {
print('primit $d');
}
}
Rezultat
Am creat iterable-ul, nimic calculat încă.
calculez 7
primit 14
calculez 9
primit 18
calculez 10
primit 20
Greșeli frecvente
- Te aștepți ca
mapsauwheresă modifice lista. Ele returnează un iterable nou și leneș; lista inițială rămâne neschimbată. - Folosești de mai multe ori un iterable leneș cu o funcție costisitoare sau cu efecte (afișări, numărători). Fiecare parcurgere recalculează totul; salvează rezultatul cu
toList().
Comenzi înrudite
Iterable.map: Transformă fiecare element cu o funcție și returnează un iterable nou, leneș, cu rezultatele.Iterable.where: Păstrează doar elementele care trec un test; whereType păstrează doar elementele de un anumit tip.Iterable.toList: toList copiază elementele într-o listă nouă; toSet le copiază într-un set nou, fără duplicate.List: Lista din Dart: elemente în ordine, accesate după poziție, care poate crește sau scădea.Set: Colecție fără elemente duplicate: fiecare valoare apare o singură dată, iar căutarea este rapidă.Iterator: Obiectul care parcurge un Iterable pas cu pas; for-in îl folosește în spate prin getter-ul iterator.