Yes. OTOH, with try_for_each
you need to introduce some new moves
fn matching_or_last<I, F>(i: I, mut predicate: F) -> Option<I::Item>
where
I: IntoIterator,
F: FnMut(&I::Item) -> bool,
{
let mut last = None;
i.into_iter()
.try_for_each(|elem| {
if predicate(&elem) {
Err(elem)
} else {
last = Some(elem);
Ok(())
}
})
.err()
.or(last)
}
(I hope the code behaves correctly)
because now there’s the Some(elem)
values being moved into last
. It’s all a trade-off and no solution is strictly better than any other in every way, I guess.
Edit: Just noticing I’m basically re-implementing find_map
with that Ok(())
, Err(elem)
and .err()
dance.
fn matching_or_last<I, F>(i: I, mut predicate: F) -> Option<I::Item>
where
I: IntoIterator,
F: FnMut(&I::Item) -> bool,
{
let mut last = None;
i.into_iter()
.find_map(|elem| {
if predicate(&elem) {
Some(elem)
} else {
last = Some(elem);
None
}
})
.or(last)
}
Furthermore, find_map
is a method that iterators from crates other than std
can implement efficiently.