0

I have a nested Vec structure where I need to convert the deepest Vec into a tuple. Consider the following example:

fn main() { let input = vec![vec![vec![vec![1.0, 2.0]]]]; let output: Vec<Vec<Vec<(f64, f64)>>> = input .iter() .map(|r1| { r1.iter() .map(|r2| r2.iter().map(|r3| (r3[0], r3[1])).collect()) .collect() }) .collect(); } 

I make the assumption that there are at least two values in the deepest vector, but if there aren't, then this code will fail. I'd like to have main return an error to indicate this, but because the indexing is in the iterator chain, I cannot simply use ? or return an error.

I'd like to not turn this whole thing into for loops. Assuming this, what are my options and what is idiomatic?

2
  • 1
    Did you read this? doc.rust-lang.org/rust-by-example/error/… Commented Aug 26, 2019 at 5:26
  • a vec of vec of vec is the worst thing to do, also call the 3 stars programmers in C. you should use ndarray Commented Aug 26, 2019 at 16:05

1 Answer 1

2

Result<FromIterator<Item = T>, E> implements FromIterator<Result<T, E>>. You can collect an iterator of Results into a Result of a collection and use ? on the Result.

Moreover, since it is FromIterator, you can recursively collect the result, directly collecting an iterator of Results into a Result of Vec.

fn main() -> Result<(), &'static str> { let input = vec![vec![vec![vec![1.0, 2.0]]]]; let output: Vec<Vec<Vec<(f64, f64)>>> = input .iter() .map(|r1| { r1.iter() .map(|r2| { r2.iter() .map(|r3| { if r3.len() >= 2 { Ok((r3[0], r3[1])) } else { Err("Bad") } }) .collect::<Result<Vec<_>, &str>>() }) .collect::<Result<Vec<_>, &str>>() }) .collect::<Result<Vec<_>, &str>>()?; Ok(()) } 

playground

Sign up to request clarification or add additional context in comments.

1 Comment

By the way, after I passed this to rustfmt, it looks even more spaghetti than using three for loops.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.