Find or return last element of iterator

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.

1 Like