Iterator::find_map în Rust

Aplică o funcție care returnează Option pe fiecare element și dă primul rezultat Some; se oprește acolo.

Sintaxă
fn find_map<B, F>(&mut self, f: F) -> Option<B>
where F: FnMut(Self::Item) -> Option<B>

Ce face Iterator::find_map

find_map(|x| ...) este filter_map(..).next(): caută primul element pentru care closure-ul returnează Some(y) și returnează acel Some(y). Dacă toate dau None, rezultatul este None.

Este util când „a găsi” și „a extrage” sunt același pas: primul text care se poate citi ca număr, prima linie care conține o anumită cheie, primul utilizator cu email completat.

Parametri

Parametru Descriere
f Closure care returnează Some(rezultat) pentru elementul căutat.

Ce returnează

Option<B>.

Exemple

Exemplul 1: Primul număr valid

fn main() {
    let raspunsuri = ["nu știu", "", "42", "17"];
    let primul: Option<u32> = raspunsuri.iter().find_map(|s| s.parse().ok());
    println!("{:?}", primul);
}

Rezultat

Some(42)

Exemplul 2: Valoarea unei chei dintr-o configurare

fn valoare<'a>(config: &'a str, cheie: &str) -> Option<&'a str> {
    config.lines().find_map(|linie| {
        let (k, v) = linie.split_once('=')?;
        (k.trim() == cheie).then(|| v.trim())
    })
}

fn main() {
    let config = "# server\nhost = dexblog.ro\nport = 443\n";
    println!("{:?}", valoare(config, "port"));
    println!("{:?}", valoare(config, "user"));
}

Rezultat

Some("443")
None

Greșeli frecvente

  • Scrii .map(f).find(|o| o.is_some()).flatten(). find_map(f) e echivalent și mai clar.
  • Te aștepți ca find_map să returneze elementul original: returnează rezultatul closure-ului.

Comenzi înrudite

  • Iterator::find: Returnează primul element care îndeplinește condiția, în Some, sau None dacă niciunul nu o îndeplinește.
  • Iterator::filter_map: Transformă și filtrează într-un singur pas: păstrează valorile din Some(..) returnate de funcție și sare peste None.
  • Iterator::position: Returnează poziția (indexul de la 0) primului element care îndeplinește condiția, sau None.