Iterator::find în Rust

Returnează primul element care îndeplinește condiția, în Some, sau None dacă niciunul nu o îndeplinește.

Sintaxă
fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where P: FnMut(&Self::Item) -> bool

Ce face Iterator::find

find(|x| cond) parcurge elementele până la primul care îndeplinește condiția și îl returnează în Some; nu mai verifică restul. Dacă nu găsește nimic, returnează None.

Ca la filter, closure-ul primește o referință la element. Pe v.iter(), elementul este &T, deci closure-ul primește &&T (modelul |&&x|), iar rezultatul este Option<&T>. Pentru ultimul element care îndeplinește condiția există rfind; pentru poziție, position.

Parametri

Parametru Descriere
predicate Condiția verificată pe &element.

Ce returnează

Option<Self::Item>.

Exemple

Exemplul 1: Primul număr mare și primul oraș cu „B”

fn main() {
    let numere = [3, 8, 12, 5, 20];
    println!("{:?}", numere.iter().find(|&&n| n > 10));
    println!("{:?}", numere.iter().find(|&&n| n > 100));

    let orase = ["Iași", "Cluj", "Brașov", "Bacău"];
    if let Some(o) = orase.iter().find(|o| o.starts_with('B')) {
        println!("primul oraș cu B: {o}");
    }
}

Rezultat

Some(12)
None
primul oraș cu B: Brașov

Exemplul 2: Căutare într-o listă de produse

struct Produs {
    cod: u32,
    nume: &'static str,
    stoc: u32,
}

fn main() {
    let produse = vec![
        Produs { cod: 101, nume: "pâine", stoc: 0 },
        Produs { cod: 102, nume: "lapte", stoc: 12 },
        Produs { cod: 103, nume: "unt", stoc: 4 },
    ];
    match produse.iter().find(|p| p.cod == 103) {
        Some(p) => println!("{}: {} bucăți", p.nume, p.stoc),
        None => println!("cod inexistent"),
    }
    let primul_epuizat = produse.iter().find(|p| p.stoc == 0).map(|p| p.nume);
    println!("primul produs epuizat: {:?}", primul_epuizat);
}

Rezultat

unt: 4 bucăți
primul produs epuizat: Some("pâine")

Greșeli frecvente

  • Scrii |x| x > 10 pe v.iter(): tipul este &&i32. Folosește |&&x| x > 10 sau |x| **x > 10.
  • Folosești filter(..).next(): e același lucru cu find(..), doar mai lung.
  • Cauți și transformi în doi pași (find + map) când transformarea poate eșua: find_map face ambele.

Comenzi înrudite

  • Iterator::find_map: Aplică o funcție care returnează Option pe fiecare element și dă primul rezultat Some; se oprește acolo.
  • Iterator::position: Returnează poziția (indexul de la 0) primului element care îndeplinește condiția, sau None.
  • Iterator::any: any verifică dacă măcar un element îndeplinește condiția; all verifică dacă toate o îndeplinesc. Se opresc cât de repede pot.
  • Iterator::filter: Păstrează doar elementele pentru care condiția dată returnează true; restul sunt sărite.
  • DoubleEndedIterator: Iterator care poate produce valori și de la coadă (next_back); permite rev(), rfind() și parcurgerea din ambele capete.