Iterator::map_while în Rust

Transformă elementele cât timp funcția returnează Some și se oprește la primul None.

Sintaxă
fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where P: FnMut(Self::Item) -> Option<B>

Ce face Iterator::map_while

map_while(|x| ...) este combinația dintre map și take_while: closure-ul returnează Option. Cât timp primești Some(y), iteratorul produce y; la primul None, se oprește definitiv.

Comparativ: filter_map sare peste None și continuă, map_while se oprește la primul None. Este util pentru citirea datelor valide până la prima linie greșită sau goală. 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
predicate Closure care returnează Some(valoare) ca să continue sau None ca să se oprească.

Ce returnează

Un iterator MapWhile.

Exemple

Exemplul 1: Numere până la primul text greșit

fn main() {
    let intrare = ["12", "7", "abc", "30"];
    let pana_la_eroare: Vec<u32> = intrare.iter().map_while(|s| s.parse().ok()).collect();
    let toate_valide: Vec<u32> = intrare.iter().filter_map(|s| s.parse().ok()).collect();
    println!("map_while:  {:?}", pana_la_eroare);
    println!("filter_map: {:?}", toate_valide);
}

Rezultat

map_while:  [12, 7]
filter_map: [12, 7, 30]

Exemplul 2: Liniile de antet ale unui mesaj

Antetul se termină la prima linie fără „: ”, aici linia goală.

fn main() {
    let mesaj = "From: ana@exemplu.ro\nSubject: Ședință\nDate: luni\n\nNe vedem la 10.";
    let antet: Vec<(&str, &str)> = mesaj.lines().map_while(|l| l.split_once(": ")).collect();
    for (camp, valoare) in &antet {
        println!("{camp} = {valoare}");
    }
}

Rezultat

From = ana@exemplu.ro
Subject = Ședință
Date = luni

Greșeli frecvente

  • Folosești map_while când vrei să sari peste valorile greșite: se oprește la prima. Pentru a sări folosește filter_map.
  • Te aștepți ca map_while să semnaleze eroarea: oprirea este tăcută. Pentru a primi eroarea, colectează în Result<Vec<_>, _>.

Comenzi înrudite

  • Iterator::take_while: take_while dă elemente cât timp condiția e adevărată și se oprește la primul care nu o îndeplinește; skip_while sare până atunci.
  • Iterator::filter_map: Transformă și filtrează într-un singur pas: păstrează valorile din Some(..) returnate de funcție și sare peste None.
  • Iterator::scan: Ca fold, dar produce câte un rezultat după fiecare element: o stare actualizată pas cu pas, de exemplu un total cumulat.
  • Iterator::map: Transformă fiecare valoare a iteratorului cu o funcție și dă un iterator cu rezultatele; nu calculează nimic până la consumare.