C# ゼロから理解するラムダ式:C#でLINQのWhereの使い方を解説 #14

前回はLINQを学ぶための導入として基礎知識を解説しました。ここからは本格的にLINQを紹介していきますLINQを使うためにはラムダ式の理解が欠かせませんので、ラムダ式がまだ完全でない人は「C# ゼロから理解するラムダ式:C#でラムダ式を書く方法 #9」をもう一度だけ復習しておきましょう。

この記事では主にLINQの基礎ともいえるWhereメソッドを学びます。WhereメソッドはLINQの根底部分を成しており、かなりの頻度で使用するの知識なので必ず押さえておきましょう。

LINQのWhereメソッド

LINQにおけるWhereメソッドは、コレクションのフィルタリングの機能を有します。例えばコレクションの中で特定の条件を満たすもの(例えば偶数や奇数、10以上の数など)を抽出する役割があります。

基本的な構文は以下の通りで、Whereメソッドの括弧内に条件を匿名メソッドかラムダ式で記述します。

(コレクション).Where(条件)

上記の場合の戻り値はIEnumerable型ですので遅延実行をサポートする機能となります。ToArrayメソッドヤToListメソッドを使用してインスタンス化する使用方法が多いですね。

LINQのWhereメソッドを書く方法

ではWhereメソッドのサンプルを紹介します。新規のコンソールアプリケーションを作成して、以下を記述して実行してみてください。

using System;
using System.Linq;

namespace App14
{
    class Program
    {
        static void Main(string[] args)
        {
            //1から10までのコレクションを作成する
            var numbers = Enumerable.Range(1, 10);
            foreach(var item in numbers.Where(x => x % 2 == 0))
            {
                //偶数だけを出力する
                Console.WriteLine(item.ToString());
            }
            Console.ReadLine();
        }
    }
}

Whereメソッドは以下の箇所になります。foreach文の元コレクションを作成するようにしています。Whereの括弧内に条件を渡してフィルタリングを実行しています。

numbers.Where(x => x % 2 == 0)

「x => x % 2 == 0」を満たすコレクションの要素だけを抽出しているのがわかるかと思います。このように記述することでforeach文内にif文を記述する必要がなく、ネストを浅く保つことができます。

また、特定のクラスの要素に対するフィルタリングも行うことができます。別のアプリケーションを作成して試してみましょう。

using System;
using System.Collections.Generic;
using System.Linq;

namespace App15
{
    class Program
    {
        public class Menu
        {
            public int Price { get; set; }
            public string Name { get; set; }
        }

        static void Main(string[] args)
        {
            var menuList = new List<Menu>()
            {
                new Menu(){ Price = 1500, Name = "ハンバーグ定食" },
                new Menu(){ Price = 900, Name = "唐揚げ定食" },
                new Menu(){ Price = 2000, Name = "ステーキセット" },
            };

            //1000円以上のメニューだけ表示する
            foreach(var menu in menuList.Where(x => x.Price >= 1000))
            {
                Console.WriteLine($"{ menu.Name }:{ menu.Price }円");
            }
            Console.ReadLine();
        }
    }
}

上記のアプリケーションでは、Priceプロパティが1000以上のものだけを抜き取って表示するようにフィルタリングした例です。Whereの各要素の中で括弧内の条件を満たすものだけを抽出します。

menuList.Where(x => x.Price >= 1000)

「x => 」の「x」は「menuList」の各要素、すなわち「Menu」クラスのインスタンス該当します。左側が引数にあたるので、「x.Price」は「Menu」クラスの各要素のPriceプロパティを示しています。

ほかにもメニューを追加してみたり、条件を変えてみたりして色々と試してみるとWhereの使い方も分かるんじゃないかなと思います。例えば「x.Price <= 1000」としてみたり「x.Price == 900」と変えてみて実行してみてください。

//1000円以下でフィルタリングする
menuList.Where(x => x.Price <= 1000)

//900円のメニューでフィルタリングする
menuList.Where(x => x.Price == 900)

LINQにおけるWhereメソッドはフィルタリングをすることができます。LINQに慣れるまではWhereメソッドを連発してみて下さい。LINQを深く知っていく過程でWhereメソッドが不要な場面も出てきますが、当面、慣れるまではWhereをたくさん使ってLINQの恩恵を受けてみてください。