0Pricing
Learn Rust Coding · レッスン

map、filter、collect

シーケンスを変換します

「map、filter、collect」はCoddyKit上の無料Learn Rust Codingレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLearn Rust Coding学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Learn Rust Codingコースには全4レッスンが含まれています。

シーケンスの変換

イテレータパイプラインで主に使うメソッドは3つあります。mapは各要素を変換し、filterは一部の要素を残し、collectは結果をコレクションにまとめます。

これらを組み合わせると、多くの手動ループを短く読みやすいチェーンに置き換えられます。

map: 1つ入力して1つ出力

mapはすべての要素にクロージャを適用し、変換後の値を生成します。要素数は変わらず、値だけが変わります。

遅延評価されるため、クロージャはイテレータが消費されるときにだけ実行されます。

fn main() {
    let nums = vec![1, 2, 3];
    let doubled: Vec<i32> = nums.iter().map(|x| x * 2).collect();
    println!("{:?}", doubled);
}

mapは型を変更できる

mapの出力型は入力型と同じである必要はありません。ここでは数値を文字列に変換します。

そのためmapは、データをある形から別の形へ変換するのに最適です。

fn main() {
    let nums = vec![1, 2, 3];
    let labels: Vec<String> = nums.iter().map(|x| format!("n{}", x)).collect();
    println!("{:?}", labels);
}

filter: 必要なものだけ残す

filterはboolを返すクロージャを受け取ります。その結果がtrueになる要素は残り、それ以外は破棄されます。

クロージャは参照を受け取るため、*でデリファレンスするか、パターンマッチングを使うことがよくあります。

fn main() {
    let nums = vec![1, 2, 3, 4, 5, 6];
    let evens: Vec<i32> = nums.into_iter().filter(|x| x % 2 == 0).collect();
    println!("{:?}", evens);
}

mapとfilterのチェーン

アダプターは自由につなげられます。順序が重要で、各要素はチェーンを上から下へ順に通過します。

ここでは偶数を残してから、残った値を二乗します。

fn main() {
    let result: Vec<i32> = (1..=6)
        .filter(|x| x % 2 == 0)
        .map(|x| x * x)
        .collect();
    println!("{:?}", result);
}

Vecにcollectする

collectはイテレータを消費し、コレクションを構築します。使用できるコレクション型が多いため、通常は対象の型を注釈します。

ターボフィッシュ構文collect::<Vec<_>>()を使えば、変数に型を注釈する代わりにできます。

fn main() {
    let squares = (1..=4).map(|x| x * x).collect::<Vec<i32>>();
    println!("{:?}", squares);
}

Stringにcollectする

collectはベクタに限られません。charのイテレータはStringにcollectできます。

Rustは対象の型を使って、要素をどのように組み立てるかを決定します。

fn main() {
    let shouted: String = "hello".chars().map(|c| c.to_ascii_uppercase()).collect();
    println!("{}", shouted);
}

HashMapにcollectする

キーと値のタプルのイテレータは、HashMapにcollectできます。zipで要素を組み合わせるか、mapでタプルを作成します。

2つの並行するシーケンスからルックアップテーブルを構築する、すっきりした方法です。

use std::collections::HashMap;

fn main() {
    let map: HashMap<i32, i32> = (1..=3).map(|x| (x, x * x)).collect();
    println!("{:?}", map.get(&2));
}

3つすべてを組み合わせる

典型的なパイプラインは文章のように読めます。要素を取り出し、絞り込み、変換し、まとめます。

ここでは3文字より長い単語を残し、大文字に変換します。

fn main() {
    let words = vec!["hi", "rust", "go", "code"];
    let kept: Vec<String> = words
        .into_iter()
        .filter(|w| w.len() > 3)
        .map(|w| w.to_uppercase())
        .collect();
    println!("{:?}", kept);
}

filter_map: 絞り込みと変換を同時に行う

filter_mapはOptionを返すクロージャを適用します。Some(v)は残されてアンラップされ、Noneは破棄されます。

一部の入力が無効になる可能性があるパース処理で特に役立ちます。

fn main() {
    let inputs = vec!["1", "two", "3"];
    let nums: Vec<i32> = inputs
        .into_iter()
        .filter_map(|s| s.parse::<i32>().ok())
        .collect();
    println!("{:?}", nums);
}

このパターンが優れている理由

map/filter/collectパイプラインは宣言的です。ループをどのように行うかではなく、求める結果を記述します。これにより、オフバイワンエラーや途中の可変状態を避けられます。

さらに遅延評価のおかげで、ステップの間に一時的なベクタが作られることもありません。

クイックチェック

シーケンスの変換について、どれだけ理解できているか確認しましょう。

まとめ

実用的なイテレータパイプラインを構築できるようになりました。

  • mapは各要素を変換し、型を変更することもできます
  • filterは述語がtrueになる要素を残します
  • collectは結果をVec、String、HashMapなどにまとめます
  • filter_mapはOptionを使って、1つのステップで絞り込みと変換を行います

よくある質問

「map、filter、collect」レッスンは無料ですか?

はい。「map、filter、collect」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Learn Rust Codingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Learn Rust Codingコースには全4レッスンが含まれています。

「map、filter、collect」で何を学びますか?

シーケンスを変換します ブラウザで直接実行するハンズオンコードでLearn Rust Codingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Learn Rust Codingを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのLearn Rust Codingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「map、filter、collect」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このLearn Rust Codingレッスンでコードを書いて実行できますか?

はい。すべてのLearn Rust Codingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Iteratorトレイト
  2. map、filter、collect
  3. アダプターとコンシューマー
  4. カスタムイテレーター
← Learn Rust Codingに戻る