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

はじめに

C#では、リストや配列などの「複数のデータをまとめて扱う入れ物」(コレクションと呼びます)を操作する場面が頻繁にあります。今回は、C#ならではの便利な書き方であるLINQ(リンク)を使ったコレクション操作の応用を紹介します。for文やif文と比べ、コードがすっきりする感覚をつかんでいきましょう。

foreachで書く場合のおさらい

まずは基本の書き方です。数値のリストから偶数だけを取り出し、それぞれを2倍にするコードをforeach文で書くと次のようになります。

List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };
List<int> result = new List<int>();

foreach (int n in numbers)
{
    if (n % 2 == 0)
    {
        result.Add(n * 2);
    }
}

「偶数かどうかを判定する」処理と「2倍にする」処理がif文の中に混ざっています。条件や変換の種類が増えるほど、コードは長くなりがちです。

LINQのFilter(絞り込み)とMap(変換)

C#にはLINQという、コレクション操作を短く書くための仕組みが標準で用意されています。他の言語で「フィルタ」「マップ」と呼ばれる考え方は、C#ではWhereメソッドとSelectメソッドに対応します。

  • Where(フィルタ): 条件に合う要素だけを残す
  • Select(マップ): 各要素を別の値に変換する

先ほどのコードをLINQで書き直すと次のようになります。

using System.Linq;

List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };

List<int> result = numbers
    .Where(n => n % 2 == 0)
    .Select(n => n * 2)
    .ToList();

Where(n => n % 2 == 0)で偶数だけを残し、Select(n => n * 2)で残った値を2倍にしています。n => n % 2 == 0のような書き方はラムダ式と呼ばれる簡易的な無名の関数で、「引数 => 処理」という形で短く書けます。最後のToList()は、LINQの結果をList型に変換して確定させるメソッドです。

複数の条件やメソッドをつなげる

LINQの良いところは、メソッドを「.」でつなげて処理を連結できる点です。これをメソッドチェーンと呼びます。「10より大きく偶数の値を文字列に変換し、大きい順に並べ替える」処理も、次のように1つの流れで書けます。

var result = numbers
    .Where(n => n > 10)
    .Where(n => n % 2 == 0)
    .OrderByDescending(n => n)
    .Select(n => n.ToString())
    .ToList();

foreachとif文で同じ処理を書くと入れ子が深くなりがちですが、LINQなら「何をしたいか」が処理の流れとしてそのまま読めます。Where=絞り込み、Select=変換、OrderBy=並べ替えという対応を覚えておけば、読み書きの見通しが良くなります。

他言語との違い・つまずきやすい点

Pythonのリスト内包表記や、JavaScriptのfilter・mapメソッドに慣れている人にとって、C#のLINQは考え方自体はほぼ同じです。ただし注意点もあります。

1つ目は、LINQが遅延実行という仕組みを持つ点です。WhereやSelectを書いた時点では実行されず、ToList()やforeachで結果を取り出すタイミングで初めて計算されます。元のコレクションを変更してから結果を使うと、意図しない値になることがあるので注意しましょう。

2つ目は、using System.Linq;の書き忘れです。LINQのメソッド群は名前空間(機能をまとめたグループ)としてSystem.Linqに含まれています。この一行が無いと、WhereやSelectがコンパイルエラーになります。LINQが使えないと感じたら、まずこの一文を確認しましょう。

3つ目は可読性とのバランスです。メソッドチェーンを連結しすぎると、処理内容が追いにくくなります。複雑になってきたら、途中結果を変数に代入して分割するなど、読みやすさを優先しましょう。

まとめ

C#のLINQを使うと、条件に合う要素を絞り込む「Where」、要素を別の値に変換する「Select」といった処理を、短く読みやすいコードで表現できます。foreachとif文の書き方と比べて処理の意図が伝わりやすくなる一方、遅延実行や名前空間の記述漏れなど、つまずきポイントもあります。まずはWhereとSelectから試してみましょう。

関連記事


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

参考書籍(PR)

C#をもっと学びたい方には「確かな力が身につくC#「超」入門 第2版」がおすすめです。


PR

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

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

コメント

このブログの人気の投稿

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

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

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