Iterators

find() and find_map()

The .find() and .find_map() consumer methods search an iterator sequentially (&mut self) and short-circuit as soon as the first matching element is found.

Signatures and Comparison

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

fn find_map<B, F>(&mut self, f: F) -> Option<B>
where
    Self: Sized,
    F: FnMut(Self::Item) -> Option<B>;
Method Closure Parameter Closure Return Method Return Equivalent Lazy Adapter Chain
.find(p) &Self::Item bool Option<Self::Item> iter.filter(p).next()
.find_map(f) Self::Item (by value) Option<B> Option<B> iter.filter_map(f).next()

Because both methods take &mut self rather than consuming self, the iterator remains usable after .find() or .find_map() returns, positioned immediately after the matched item.

Searching with .find() and Continuing Iteration

fn main() {
    let mut numbers = [10, 25, 42, 60, 80].into_iter();

    // Stops at 42 and leaves [60, 80] in `numbers`:
    let first_even_over_30 = numbers.find(|&n| n > 30 && n % 2 == 0);
    let next_after_match = numbers.next();

    println!("Found:     {first_even_over_30:?}");
    println!("Next item: {next_after_match:?}");
}
Found:     Some(42)
Next item: Some(60)

Searching and Transforming in One Step with .find_map()

Use .find_map() when checking whether an item matches also produces a parsed or extracted value (avoiding repeating the work after .find()):

fn first_valid_port(env_vars: &[(&str, &str)]) -> Option<u16> {
    env_vars.iter().find_map(|(key, val)| {
        if *key == "APP_PORT" || *key == "PORT" {
            val.parse::<u16>().ok()
        } else {
            None
        }
    })
}

fn main() {
    let env = [
        ("HOST", "127.0.0.1"),
        ("APP_PORT", "not_a_port"),
        ("PORT", "8080"),
        ("PORT", "9090"),
    ];

    println!("Resolved port: {:?}", first_valid_port(&env));
}
Resolved port: Some(8080)

Searching from the Back with .rfind()

On any DoubleEndedIterator (such as a slice or VecDeque iterator), .rfind(predicate) searches from the back toward the front and returns the last matching element in $O(k)$ steps from the end.