Iterating over Results

An Iter::map operation might fail, for example:

1. fn main() {
2. let strings = vec!["tofu", "93", "18"];
3. let possible_numbers: Vec<_> = strings
4. .into_iter()
5. .map(|s| s.parse::<i32>())
6. .collect();
7. println!("Results: {:?}", possible_numbers);
8. }

Let’s step through strategies for handling this.

Ignore the failed items with filter_map()

filter_map calls a function and filters out the results that are None.

1. fn main() {
2. let strings = vec!["tofu", "93", "18"];
3. let numbers: Vec<_> = strings
4. .into_iter()
5. .map(|s| s.parse::<i32>())
6. .filter_map(Result::ok)
7. .collect();
8. println!("Results: {:?}", numbers);
9. }

Fail the entire operation with collect()

Result implements FromIter so that a vector of results (Vec<Result<T, E>>) can be turned into a result with a vector (Result<Vec<T>, E>). Once an Result::Err is found, the iteration will terminate.

1. fn main() {
2. let strings = vec!["tofu", "93", "18"];
3. let numbers: Result<Vec<_>, _> = strings
4. .into_iter()
5. .map(|s| s.parse::<i32>())
6. .collect();
7. println!("Results: {:?}", numbers);
8. }

This same technique can be used with Option.

Collect all valid values and failures with partition()

1. fn main() {
2. let strings = vec!["tofu", "93", "18"];
3. let (numbers, errors): (Vec<_>, Vec<_>) = strings
4. .into_iter()
5. .map(|s| s.parse::<i32>())
6. .partition(Result::is_ok);
7. println!("Numbers: {:?}", numbers);
8. println!("Errors: {:?}", errors);
9. }

When you look at the results, you’ll note that everything is still wrapped in Result. A little more boilerplate is needed for this.

1. fn main() {
2. let strings = vec!["tofu", "93", "18"];
3. let (numbers, errors): (Vec<_>, Vec<_>) = strings
4. .into_iter()
5. .map(|s| s.parse::<i32>())
6. .partition(Result::is_ok);
7. let numbers: Vec<_> = numbers.into_iter().map(Result::unwrap).collect();
8. let errors: Vec<_> = errors.into_iter().map(Result::unwrap_err).collect();
9. println!("Numbers: {:?}", numbers);
10. println!("Errors: {:?}", errors);
11. }