## Keyboard shortcuts

Press `←` or `→` to navigate between chapters

Press `S` or `/` to search in the book

Press `?` to show this help

Press `Esc` to hide this help

# `Result`をイテレートする

`Iter::map`オペレーションは失敗することもあります。例えば、

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

ここでは、この対処法についてみてみましょう。

## `filter_map()`を使って失敗した要素のみを無視する

`filter_map`は関数を呼び出し、結果が`None`になるものだけ取り除きます。

    fn main() {
        let strings = vec!["tofu", "93", "18"];
        let numbers: Vec<_> = strings
            .into_iter()
            .filter_map(|s| s.parse::<i32>().ok())
            .collect();
        println!("Results: {:?}", numbers);
    }

## Collect the failed items with `map_err()` and `filter_map()`

`map_err` calls a function with the error, so by adding that to the previous `filter_map` solution we can save them off to the side while iterating.

    fn main() {
        let strings = vec!["42", "tofu", "93", "999", "18"];
        let mut errors = vec![];
        let numbers: Vec<_> = strings
            .into_iter()
            .map(|s| s.parse::<u8>())
            .filter_map(|r| r.map_err(|e| errors.push(e)).ok())
            .collect();
        println!("Numbers: {:?}", numbers);
        println!("Errors: {:?}", errors);
    }

## `collect()`で処理全体を失敗させる

`Result`は、それらのベクタ(`Vec<Result<T, E>>`)からベクタのそれ(`Result<Vec<T>, E>`)へと変換できるようにするため、`FromIterator`を実装します。`Result::Err`が見つかり次第、イテレーションは終了します。

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

同じテクニックは、`Option`を用いて行うこともできます。

## `partition()`を使って全ての正常な値と失敗をまとめる

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

結果を見てみると、まだ全て`Result`にラップされていることに気づくでしょう。もう少しのボイラープレートが必要です。

    fn main() {
        let strings = vec!["tofu", "93", "18"];
        let (numbers, errors): (Vec<_>, Vec<_>) = strings
            .into_iter()
            .map(|s| s.parse::<i32>())
            .partition(Result::is_ok);
        let numbers: Vec<_> = numbers.into_iter().map(Result::unwrap).collect();
        let errors: Vec<_> = errors.into_iter().map(Result::unwrap_err).collect();
        println!("Numbers: {:?}", numbers);
        println!("Errors: {:?}", errors);
    }