【C#】ListのWhereの読み方・書き方はWhereを使わないコードと比較して理解しよう

C#のコードを見ていると、Where(m => m.name == “tanaka”) のように

矢印のような「=>」で書かれていたり、
定義されていない変数がいきなり出てきたりと、

お困りの方に向けて書きます。

「=>」を使ったコードを理解するために
高頻出のListで使用されるWhereを題材にコード例出して解説していきます。

WhereとWhereを使わないコードとを比較してみよう

早速ですが、Whereの中でやっていることとWhereを使わないコードで比較していきましょう。
ポイントは以下です。

  • 「=>」 の左側はvarと一緒
  • 「=>」の右側にはif文の処理相当
  • foreachが裏にいる

コードを比較するにあたり利用するListはこちら


まずはWhereで6歳以上の生徒を抜き出してみましょう。


次にWhereを使わないで書いてみます。


準備ができましたので、コードを比較していきます。

「=>」 の左側はvarと一緒


「=>」 の左側はvarに相当します。

今回の例でいうと

foreach (var student in students)

のvar student部分ですね。

ここでstudentはstudentsから、ひとつピックアップしたものを指しています。

つまり「=> の手前」は変数宣言に相当するので、好きな名称で定義することができます。


この3つのWhereを使った記述は、すべて6歳以上の生徒を抜きだすことができます。

けれども、できるだけListであるstudentsに則した名前を付けてあげると読みやすくなります。

「=>」の右側にはif文の処理相当

「=>」の右側にはif文の条件に相当するものが入ります。

今回の例では6歳以上の生徒を抜き出していますが
こちらも自由に変えることができます。試しにtanakaを抜き出してみましょう。



if文の条件以外の処理は一緒ですね。

foreachが裏で動いている

ここまで見ていただいたとおり、比較対象としてWhereを使わないコードには
foreachがありましたね。

Listは同じものが繰り返されたものをデータとして持っています。

この特徴があるためWhereなどのList操作には、裏にforeach文があることをイメージすると良いです。

Whereとはforeachとifの組み合わせを関数にしたもの

「6歳以上の生徒を取得する」と「tanakaを取得する」は比較する条件以外は共通していました

ifの条件だけ違うだけで、それ以外のforeachで繰り返したいこと、ifで比較することはすべて同じです。

つまり、ifの条件だけ入れ替えて、あとは再利用するために作られた関数こそがWhereになります。

「=>」を使ったコードに馴染みにくいのは関数型だから

「=>」を使ったコードが難しいと感じるにはいくつかの要因があります。

  • 「値」ではなく「処理」を引数にとる
  • 比較的新しい書き方
  • 講座や研修では習わない

Whereは処理を引数にとる

違うのはif文の中身だけで「比較する条件以外は共通」していますね。

Whereはこの比較する条件・処理を引数にとります。

このときの引数は、処理=関数なので関数型とも呼ばれます。

関数型は一つポイントです。

なぜなら関数は値を引数にとって動かすことから習うことが多いと思います。

しかし、Whereの書き方を初めてみた人にとっては、
処理を引数にとるという行為を初めて目にするので混乱するのではないでしょうか。

講座や研修では習わないこともある

新人プログラマの講座を見学しに行く機会が何度かありましたが、
そこで必ずしも関数型を教えていたわけではありませんでした。

やっていたとしても重点的には説明はしていない印象です。

もしかしたら、プログラミングを始めたばかりでは、そもそも覚えることが多いので、
混乱させないように、あえて関数型は省いていたりするのかもしれませんね。

「=>」は比較的新しい書き方

関数型のプログラミングはトレンドになっていたものの、
最初期のC#にはその機能自体ありませんでした。

つまり、


のような書き方は最初できませんでした。

バージョンアップによって少しずつ機能を拡張していき、
関数型を簡単に取り扱えるようになってきた経緯があり、

「=>」も近年になってできるようになりました。

難しいと感じたなら形をなぞって使ってみよう

とは言っても、いつかは関数型のコードにでくわします。
本記事でも関数的なコードの読み方の助けになればと思い記事を書いてます。
ですが、必ずしもお力になれない可能性があります。

そんなときは

究極、理解できないものは理解できないものとして、
ひたすらに使い続ける解決策(?)を提案させてください。

根性論的かもしれませんが、私自身は慣れ→理解の順番でWhereなどのメソッドを使えるようになったので
難しいと感じたとしても、まずは書いてみることをオススメします。

Listの操作は汎用的な知識になる

分からないままでも使い続けるには理由があります。

Listの操作は汎用的ゆえ、コーディングの基盤の一つとです。
「記述するコード量を圧縮」「メンテナンス性に優れる」など
のメリットもありますが、ほかには次のようなメリットもあります。

  • 様々なプログラムで使える
  • 便利機能が充実している
  • ほかの言語でも流用できる

様々なプログラムで使える

List型の操作は、データを扱う場合、かなりの頻度で出てきます。
データを保存する先はデータベースが主になるでしょう。

データベースの構造はListなど配列と同じように
同じプロパティを持ったデータたちが並んでいます。

つまり、データベースを使うプログラムは、ほぼ100%配列とListやの出番があります。

ですので、List操作の書きかたを覚えてしまえば、
どんなプログラムを書くにしても応用が利くので、
ぜひ注目してみてください。

便利機能が充実

高頻出ゆえに便利機能が充実
かなりのプログラムでListが活躍できることから、
Listの操作は充実しています。

Whereのように抽出する作業以外にも、最大値・最小値を取得したり、
ほしいオブジェクトがListの中にあるかどうか調べる方法があったりと、
様々な便利機能があります。

機能一覧が見たい方はこちらをどうぞ。

https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable

様々な言語でも流用できる

Whereのような書き方は、ほかの言語でも頻出の書き方です。
以下の記事ではjavascriptを例に説明しています。

>>FOR文を使わないで配列を活用する

C#はWhereですけれどもjavascriptはfilterですね。

まとめ

ListのWhereの読み方・書き方について最後にまとめです。

  • Whereはvarのように自由に「変数定義する部分」と「処理を渡す」で構成されている
  • 関数型の書きかたを覚えると様々な状況でつかえる