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.