Ce face Iterator::scan
scan(stare_initiala, |stare, x| ...) ține o stare mutabilă pe care closure-ul o primește ca &mut la fiecare element. Closure-ul returnează Option: Some(y) produce y, iar None oprește iteratorul.
Cazul tipic este suma cumulată (soldul după fiecare tranzacție, totalul pe zile). Spre deosebire de fold, care dă doar rezultatul final, scan dă toate rezultatele intermediare. Ca toate adaptoarele, este leneș: nu face nimic până când iteratorul nu este consumat (de for, collect, sum, count etc.).
Parametri
| Parametru | Descriere |
|---|---|
initial_state |
Valoarea de pornire a stării. |
f |
Closure care primește &mut stare și elementul curent, și returnează Some(valoare) sau None pentru oprire. |
Ce returnează
Un iterator Scan.
Exemple
Exemplul 1: Total cumulat al vânzărilor
fn main() {
let vanzari = [120, 80, 200, 50, 150];
let cumulat: Vec<u32> = vanzari
.iter()
.scan(0, |total, &v| {
*total += v;
Some(*total)
})
.collect();
println!("pe zile: {:?}", vanzari);
println!("cumulat: {:?}", cumulat);
}
Rezultat
pe zile: [120, 80, 200, 50, 150]
cumulat: [120, 200, 400, 450, 600]
Exemplul 2: Soldul contului, oprit la primul minus
Când soldul ar deveni negativ, returnăm None, iar tranzacțiile de după nu mai sunt procesate.
fn main() {
let tranzactii = [100, -30, -50, -40, 200];
let solduri: Vec<i32> = tranzactii
.iter()
.scan(0, |sold, &t| {
if *sold + t < 0 {
return None;
}
*sold += t;
Some(*sold)
})
.collect();
println!("solduri: {:?}", solduri);
println!("tranzacții acceptate: {} din {}", solduri.len(), tranzactii.len());
}
Rezultat
solduri: [100, 70, 20]
tranzacții acceptate: 3 din 5
Greșeli frecvente
- Folosești
scancând ai nevoie doar de rezultatul final:foldsausumsunt mai simple. - Uiți steluța la stare:
total += vnu compilează, pentru cătotaleste&mut. Scrie*total += v.
Comenzi înrudite
Iterator::fold: Combină toate elementele într-o singură valoare, pornind de la o valoare inițială și aplicând o funcție pas cu pas.Iterator::map_while: Transformă elementele cât timp funcția returnează Some și se oprește la primul None.Iterator::try_fold: Ca fold, dar funcția returnează Option sau Result și oprirea are loc la primul None sau Err.iter::successors: Creează un șir în care fiecare element se calculează din cel dinainte; se oprește când funcția returnează None.