I am searching for something like this:
let iter = vec![1, 2, 40, 3].into_iter();
let (pos, elt) = iter.position_find(|&x| x > 10);
// ^ does not exist
println!("{pos} {elt}"); // 2 40
Both Iterator::position
and Iterator::find
advance the iterator, so I can't use both unless I'm cloning the iterator, which is unnecessary here.
You can use find
together with enumerate
:
let iter = vec![1, 2, 40, 3].into_iter();
if let Some((pos, elt)) = iter.enumerate().find(|(i, x)| x > &10) {
println!("{pos} {elt}"); // 2 40
}
If you don't want to write this out every time, you could even turn it into an extension trait to automatically implement it as a method on all iterators:
trait FindPosition: Iterator {
fn find_position<F: FnMut(usize, &Self::Item) -> bool>(
&mut self,
mut f: F,
) -> Option<(usize, Self::Item)> {
self.enumerate().find(|(i, item)| f(*i, item))
}
}
impl<I: Iterator> FindPosition for I {}
fn main() {
let mut iter = vec![1, 2, 40, 3].into_iter();
if let Some((pos, elt)) = iter.find_position(|_, x| *x > 10) {
println!("{pos} {elt}"); // 2 40
}
}