#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専用の自動化ツールをオーダーメイドで作成しています。気になる方はこちらをご覧ください。
コメント
コメントを投稿