#21 Rustで学ぶコレクション操作の応用(フィルタ・マップ的な考え方)の基本

はじめに

プログラミングを学んでいくと、配列やリストのようなたくさんのデータ(まとめて「コレクション」と呼びます)を扱う場面によく出会います。そこから条件に合うものだけを取り出したり、全部の値を別の形に変換したりしたい、と思うことも多いでしょう。多くの言語では、これを「フィルタ(filter)」や「マップ(map)」という考え方で実現します。Rustにもこの考え方はしっかり用意されていて、しかも安全性とスピードの両立にこだわった作りになっています。今回は、Rustの「イテレータ(iterator)」という仕組みを使って、コレクション操作の基本を学んでいきましょう。

イテレータとは何か

イテレータとは、簡単に言うと「コレクションの中身を1つずつ順番に取り出してくれる仕組み」のことです。RustではVec(可変長の配列のようなもの)などに対して.iter()というメソッドを呼ぶことで、このイテレータを作ることができます。イテレータそのものは値を1つずつ渡すだけの存在ですが、これにfilterやmapといった「アダプタ」と呼ばれるメソッドをつなげていくことで、柔軟なデータ加工ができるようになります。

filterで条件に合う値だけを残す

filterは「条件に合う値だけを残す」ためのメソッドです。次の例を見てみましょう。

let numbers = vec![1, 2, 3, 4, 5, 6];
let evens: Vec<&i32> = numbers.iter().filter(|n| **n % 2 == 0).collect();
println!("{:?}", evens); // [2, 4, 6]

filterには「条件」を書いた関数(ここでは無名関数、いわゆるクロージャ)を渡します。|n| **n % 2 == 0の部分は「nが偶数かどうか」を判定しています。**nのように*(アスタリスク)が2つ付いているのは、Rust特有の書き方です。iter()は値そのものではなく「参照」というアドレスのようなものを渡してくるため、参照を1段外す必要があり、それがこの*にあたります。最初は戸惑いやすいポイントなので、エラーが出たら「参照が二重になっていないか」を疑ってみてください。

mapで値を変換する

mapは「それぞれの値を別の形に変換する」ためのメソッドです。

let numbers = vec![1, 2, 3];
let doubled: Vec<i32> = numbers.iter().map(|n| n * 2).collect();
println!("{:?}", doubled); // [2, 4, 6]

filterと同じくクロージャを渡し、その戻り値が新しい値になります。最後に付いているcollect()は、イテレータの結果を実際のVecなどのコレクションに変換して確定させるためのメソッドです。これを呼ばないと、値はまだ「計算される予定」の状態のままになっています。

filterとmapを組み合わせる

filterとmapは自由に連結できます。「偶数だけを取り出して2倍にする」なら次のように書けます。

let result: Vec<i32> = numbers.iter()
    .filter(|n| **n % 2 == 0)
    .map(|n| n * 2)
    .collect();

他言語のような「ループを何重にも書く」必要がなく、処理の流れを1本の鎖(メソッドチェーン)のように書けるのがイテレータの魅力です。

Rustならではの注意点

Rustのイテレータは「遅延評価」という性質を持ちます。これはfilterやmapを書いた時点ではまだ何も実行されず、collectのように結果を求める処理を呼んで初めて計算が走る、という仕組みです。そのため無駄な計算をしにくく、処理速度の面で有利です。また、collectは戻り値の型からVecなのかHashMapなのかを自動的に判断します。ただし型がうまく推論できない場合は、collect::<Vec<i32>>()のように型を明示する必要があります。これも他の言語との違いとして覚えておくとよいでしょう。

まとめ

今回は、Rustのイテレータを使ったfilter・mapによるコレクション操作の基本を紹介しました。filterで条件に合う値を絞り込み、mapで値を変換し、最後にcollectで結果を確定させる、という流れを覚えておけば、多くのデータ加工処理をシンプルに書けるようになります。参照の外し方や遅延評価といったRust特有の癖はありますが、慣れてしまえば安全で読みやすいコードを書ける強力な道具になります。ぜひ手元のコードで試してみてください。

関連記事


本ページはプロモーションを含みます。

参考書籍(PR)

Rustをもっと学びたい方には「実践Rust入門[言語仕様から開発手法まで]」がおすすめです。


PR

コードを書かずに自動化したい方へ

「学んだけど自分の作業に組み込む時間がない」という方向けに、ダブルクリックで動くWindows専用の自動化ツールをオーダーメイドで作成しています。気になる方はこちらをご覧ください。

コメント

このブログの人気の投稿

#25 Rustで学ぶAI API(ChatGPT等)の呼び出し方の基本

#8 C++で学ぶ文字列操作の基本

#16 TypeScriptで学ぶ辞書型(マップ)の基本