How to make an iterator::filter_map / iterator::map_while but that return a Result (or Option)

Hello, I think a code example is easier to explain my goal :

fn main() {
    let data = ["1", "3", "5", "HELLO", "54"];
    let final_data = data.iter()
        .map_while_none(|string| string.parse::<u32>().ok()).collect::<Option<Vec<u32>>>()
    //   ^^^^^^^^^^^^^^
    //   Act like a `map_while` but as soon as a `None` is return,
    //  the total iterator is convert to an Option::None

    // ie final_data should be equals to None
     
    let data = ["1", "3", "5", "54"];
    let final_data = data.iter()
        .map_while_none(|string| string.parse::<u32>().ok()).collect::<Option<Vec<u32>>>()
    // here final_data should be equals to Some([1, 3, 5, 54])
}

Does such an iterator exist ? If search in the std and in the itertools crate, but I didn't find anything conclusive.

The collect method supports this directly.

fn main() {
    let data = ["1", "3", "5", "HELLO", "54"];
    let final_data = data.iter()
        .map(|string| string.parse::<u32>().ok())
        .collect::<Option<Vec<u32>>>();
}
2 Likes

It's an obvious desire to have some way to turn impl Iterator<Item = Result<T, E>> into Result<impl Iterator<Item = T>, E>.

Unfortunately, that basically can't work while preserving the laziness of iterators -- it would need to know whether there'd be any error before actually looking at elements.

So since it needs to store the elements somewhere while it looks for errors, the closest thing that's possible is impl Iterator<Item = Result<T, E>> -> Result<Collection<T>, E> instead -- which, as alice mentioned, is done with collect.

2 Likes

Actually the closest thing is the API that that collect implementation itself uses internally in its implementation. An API like process_results from itertools.

I implicitly meant "with returning a Result" in there.

If you remove that requirement, then yes, there are a bunch of other options like the error_collector I demonstrate in Partition iterator - best practice and design guidance - #5 by scottmcm.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.