0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Effective-Rustlings-jp】Day 8:明示的なループの代わりにイテレータ変換を使用することを検討しよう

Last updated at Posted at 2025-01-08

はじめに

こんにちは。細々とプログラミングをしているsotanengelです。
この記事は以下の記事の連載です。

他の連載記事 (詳細)

また本記事はEffective Rust(David Drysdale (著), 中田 秀基 (翻訳))を参考に作成されております。とてもいい書籍ですので興味を持った方は、ぜひ読んでみてください!

今日の内容

概要

Rustではイテレータを使うことで愚直にループを書くよりも効率的になる場合があります。
そこでイテレータを使って何ができるか試してみましょう。

イテレータで配列の合計値を算出しましょう

問(リンク)

以下のコードでは愚直に書いているので、itersumを使ってコードを書き直してみましょう。

コード (詳細)
#[allow(clippy::useless_vec)]
fn main() {
    let numbers = vec![1, 2, 3, 4, 5];

    // TODO: イテレータを使って簡潔に実装し直してください。
    let mut sum = 0;
    for i in 0..numbers.len() {
        sum += numbers[i];
    }

    println!("Sum: {}", sum);
}

解答(リンク)

コード参照。

コード (詳細)
#[allow(clippy::useless_vec)]
fn main() {
    let numbers = vec![1, 2, 3, 4, 5];

    // イテレータを使って合計を計算します。
    let sum: i32 = numbers.iter().sum();

    println!("Sum: {}", sum);
}

配列のnの倍数の場所にある要素を取得しましょう

問(リンク)

配列の3番目の要素だけを合計する機能をskipstep_byを使って実装してください。

コード (詳細)
#[allow(clippy::useless_vec)]
fn main() {
    let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];

    let mut sum = 0;
    let mut index = 2; // 最初の2要素をスキップ

    // TODO: イテレータを使って簡潔に実装し直してください。
    while index < numbers.len() {
        sum += numbers[index];
        index += 3; // 3つおきに要素を取得
    }

    println!("Sum of elements at multiples of 3 indices: {}", sum);
}

解答(リンク)

コード参照。

コード (詳細)
#[allow(clippy::useless_vec)]
fn main() {
    let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];

    let sum: i32 = numbers
        .iter()
        .skip(2) // 最初の2要素をスキップ
        .step_by(3) // 3つおきに要素を取得
        .sum();

    println!("Sum of elements at multiples of 3 indices: {}", sum);
}

特定の条件の要素だけ抽出しましょう

問(リンク)

奇数かつ、10未満の要素を抽出するためにfiltercollectを使って実装してください。

コード (詳細)
#[allow(clippy::useless_vec)]
fn main() {
    let numbers = vec![17, 3, 25, 8, 42, 7, 19, 6, 1, 12, 9, 5];

    let mut odd_numbers = Vec::new();

    // TODO: イテレータを使って簡潔に実装し直してください。
    for i in 0..numbers.len() {
        let x = numbers[i];
        if x % 2 != 0 && x < 10 {
            odd_numbers.push(x);
        }
    }

    println!("{:?}", odd_numbers);
}

解答(リンク)

コード参照。

コード (詳細)
#[allow(clippy::useless_vec)]
fn main() {
    let numbers = vec![17, 3, 25, 8, 42, 7, 19, 6, 1, 12, 9, 5];

    let odd_numbers: Vec<i32> = numbers
        .iter()
        .filter(|&&x| x % 2 != 0 && x < 10)
        .copied()
        .collect();

    println!("{:?}", odd_numbers);
}

ターボフィッシュ記法を使いこなそう。

問(リンク)

collectとターボフィッシュ記法を使うことで、失敗する可能性のある処理をResult型に格納して返却する実装をしてください。

コード (詳細)
fn parse_numbers(items: Vec<&str>) -> Result<Vec<i32>, std::num::ParseIntError> {
    let mut results = Vec::new();

    // TODO: イテレータを使って簡潔に実装し直してください。
    for i in 0..items.len() {
        match items[i].parse::<i32>() {
            Ok(num) => results.push(num),
            Err(e) => return Err(e),
        }
    }

    Ok(results)
}

#[allow(clippy::useless_vec)]
fn main() {
    let items = vec!["42", "93", "apple", "17"];
    let parsed = parse_numbers(items);

    match parsed {
        Ok(numbers) => println!("Parsed numbers: {:?}", numbers),
        Err(e) => eprintln!("Failed to parse: {}", e),
    }
}

解答(リンク)

コード参照。

コード (詳細)
fn parse_numbers(items: Vec<&str>) -> Result<Vec<i32>, std::num::ParseIntError> {
    items
        .into_iter()
        .map(|item| item.parse::<i32>())
        .collect::<Result<Vec<_>, _>>()
}

#[allow(clippy::useless_vec)]
fn main() {
    let items = vec!["42", "93", "apple", "17"];
    let parsed = parse_numbers(items);

    match parsed {
        Ok(numbers) => println!("Parsed numbers: {:?}", numbers),
        Err(e) => eprintln!("Failed to parse: {}", e),
    }
}

さいごに

もしも本リポジトリで不備などあれば、リポジトリのissueやPRなどでご指摘いただければと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?