【C#, LINQ】SelectとWhereの違い

【C#, LINQ】SelectとWhereの違い
2020年3月2日
スポンサーリンク

こんにちは。ゆとり(@yutori_techblog)です。

この記事は、C# LINQのSelectメソッドとWhereメソッドの違いについて簡潔にまとめています。

WhereとSelectの違い

とても簡潔に書くと次のようになります。

  • Where・・・抽出する
  • Select・・・変換する

Whereは、コレクションの要素から条件に合致したものを抽出したいときに使用します。
Selectは、コレクションのすべての要素を別の型または値に変換したいときに使用します。

Where:抽出する

Whereはコレクションの要素の中から、条件に合致するものを抽出します。

使い方

collection.Where(要素 => 抽出条件);

使用例:全員のテスト結果から、赤点の者を抽出する

次のようなテスト結果から、赤点の者を抽出します。
50点未満を赤点とします。

名前点数
A子80
B男45
C子90
D子32
E男76
//テスト結果のデータ構造を定義
struct TestResult
{
    //生徒の名前
    public string Name { get; set; }
    //テストの点数
    public int Score { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        //テスト結果をコレクションに格納
        List<TestResult> results = new List<TestResult>()
        {
            new TestResult(){Name = "A子", Score = 80},
            new TestResult(){Name = "B男", Score = 45},
            new TestResult(){Name = "C子", Score = 90},
            new TestResult(){Name = "D子", Score = 32},
            new TestResult(){Name = "E男", Score = 76},
        };

        //50点未満のデータを抽出してakatensに格納
        var akatens = results.Where(r => r.Score < 50);

        //akatensのデータをひとつずつ取り出す
        foreach (var result in akatens)
        {
            //赤点の生徒の名前を出力
            Console.WriteLine(result.Name);
        }
    }
}
結果

Whereメソッドを使うことで、50点未満のデータが抽出できています。

Select:変換する

Selectはコレクションのすべての要素に一定の処理をかけ、その変換結果を返します

使い方

collection.Select(要素 => 変換後の値);

使用例:全員のテスト結果から評価を返す

全員のテストの点数を一定の基準で評価し、結果を出力します。
この例では、点数を評価に変換するためにSelectを使用しています

struct TestResult
{
    public string Name { get; set; }
    public int Score { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        List<TestResult> results = new List<TestResult>()
        {
            new TestResult(){Name = "A子", Score = 80},
            new TestResult(){Name = "B男", Score = 45},
            new TestResult(){Name = "C子", Score = 90},
            new TestResult(){Name = "D子", Score = 32},
            new TestResult(){Name = "E男", Score = 76},
        };

        //テスト結果から評価に変換
        var evaluations = results.Select(r => GetEvaluation(r));

        //評価結果をひとつずつ取り出す
        foreach (var evaluation in evaluations)
        {
            //評価結果を出力
            Console.WriteLine(evaluation);
        }
    }

    //テスト結果から評価を取得する
    private static string GetEvaluation(TestResult result)
    {
        string evaluation;
        if(result.Score < 50)
        {
            evaluation = "赤点";
        }
        else if(result.Score < 70)
        {
            evaluation = "もう少し頑張りましょう";
        }
        else if(result.Score < 80)
        {
            evaluation = "あと一歩です";
        }
        else if (result.Score < 90)
        {
            evaluation = "よく頑張りました";
        }
        else
        {
            evaluation = "素晴らしい";
        }

        //名前:評価 の形式で出力
        return result.Name + ":" + evaluation;
    }
}
結果

Selectメソッドを使うことで、コレクションのすべての要素に一定の処理をかけ、値を変換することができています。

WhereとSelectの組み合わせ技

Where(抽出)とSelect(変換)を組み合わせて使うこともできます。
例えば、「赤点以外の生徒のテスト結果から、評価を作成する」といったことが簡単にできます。

/////略/////

//赤点でない生徒のテスト結果から評価を作成
var evaluations = results.Where(r => r.Score >= 50)      //点数が50以上に絞り込み
                         .Select(r => GetEvaluation(r)); //絞り込んだ結果から評価を取得

//評価結果をひとつずつ取り出す
foreach (var evaluation in evaluations)
{
    //評価結果を出力
    Console.WriteLine(evaluation);
}

/////略/////
結果

赤点でない生徒のテスト結果のみから、評価を作成できています。

まとめ

  • Whereメソッドは「抽出」
  • Selectメソッドは「変換」
  • 組み合わせて使用することも可能

以上です。お役に立てましたら幸いです。

ちなみに…

次の記事では、今回紹介した「Where」と「Select」を同時に行うことができる自作LINQメソッドを紹介しています。併せてご確認ください。

【C#, LINQ】WhereとSelectを同時に行いたい!→作ってみた
先日、 WhereとSelectを同時に行いたい… となりましたので、自作のLINQオペレータを作成して対応しました。この記事では、WhereとSelectを同…
yutori-techblog.com