If I have an iterator of iterators like this, I can easily flatten and collect into the vector:
pub fn bar<I, J>(iter: I) -> Result<Vec<i32>>
where
I: IntoIterator<Item = J>,
J: IntoIterator<Item = Result<i32>>,
{
iter.into_iter().flatten().collect()
}
However, I ran into a situation where I have this instead:
pub fn foo<I, J>(iter: I) -> Result<Vec<i32>>
where
I: IntoIterator<Item = Result<J>>,
J: IntoIterator<Item = Result<i32>>,
{
todo!()
}
I would still like to collect into a flat vector while propagating the first error that happens. The errors come from two different sources now – either from the outer iterator or from one of the inner iterators. The only solution I managed to come up with that avoids collecting the inner iterators into temporary vectors is this:
pub fn foo<I, J>(iter: I) -> Result<Vec<i32>>
where
I: IntoIterator<Item = Result<J>>,
J: IntoIterator<Item = Result<i32>>,
{
let mut v = vec![];
for inner in iter {
for x in inner? {
v.push(x?);
}
}
Ok(v)
}
Is there any better way to do this? Specifically, can I somehow use collect()
to take advantage of the optimizations in the FromIterator
implementation of Vec
?