English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

LINQ フィルタリング演算子 Where

LINQのフィルタリング演算子は、特定の基準に基づいてシーケンス(コレクション)をフィルタリングします。

以下のテーブルには、LINQで利用可能なすべてのフィルタリング演算子が示されています。

フィルタリング演算子説明
Where

述語関数からコレクションから値を返します。

OfType

指定されたタイプに基づいてコレクションの値を返します。ただし、それが指定されたタイプに変換できるかどうかにもよります。

Where

Where演算子(Linq拡張メソッド)は、指定された条件式に基づいてコレクションをフィルタリングし、新しいコレクションを返します。標準はラムダ式またはFuncデリゲート型として指定できます。

Where拡張メソッドには以下の2つのオーバーロードがあります。両方のオーバーロードはFuncデリゲート型の引数を受け取ります。一つのオーバーロードはFunc <TSource,bool>入力引数を必要とし、もう一つのオーバーロードはFunc <TSource,int,bool>入力引数を必要とし、intはインデックスとして使用されます:

Whereメソッドのオーバーロード:
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, 
                                                  Func<TSource, bool> predicate);
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, 
                                                  Func<TSource, int, bool> predicate);

クエリ構文のWhere子句

以下のクエリ例は、Where演算子を使用して与えられたコレクション(シーケンス)から十代の学生をフィルタリングする。それはラムダ式を使用する述語関数として機能する。

IList<Student> studentList = new List<Student>() { 
        new Student() { StudentID = 1, StudentName = "John", Age = 13}
        new Student() { StudentID = 2, StudentName = "Moin",  Age = 21 }
        new Student() { StudentID = 3, StudentName = "Bill",  Age = 18 }
        new Student() { StudentID = 4, StudentName = "Ram" , Age = 20},
        new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 } 
    };
var filteredResult = from s in studentList
                    where s.Age > 12 && s.Age < 20
                    select s.StudentName;
Dim studentList = New List(Of Student) From {
        New Student() With {.StudentID = 1, .StudentName = "John", .Age = 13},
        New Student() With {.StudentID = 2, .StudentName = "Moin", .Age = 21},
        New Student() With {.StudentID = 3, .StudentName = "Bill", .Age = 18},
        New Student() With {.StudentID = 4, .StudentName = "Ram", .Age = 20},
        New Student() With {.StudentID = 5, .StudentName = "Ron", .Age = 15}
    }
Dim filteredResult = From s In studentList
                     Where s.Age > 12 And s.Age < 20
                     Select s.StudentName

上記の例では、filteredResultはクエリ実行後に以下の学生を含むことになります。

John
Bill
Ron

上記の例のクエリでは、ラムダ式本体が以下のようになります: s.Age > 12 && s.Age < 20 を評価するためのパターン関数として集合内の各学生を渡します。Func<TSource, bool>

また、Func型デリゲートと匿名メソッドを一緒に使用して、以下のようにパターン関数として渡すことができます(出力は同じです):

Func<Student,bool> isTeenAger = delegate(Student s) { 
                                    return s.Age > 12 && s.Age < 20; 
                                };
var filteredResult = from s in studentList
                     where isTeenAger(s)
                     select s;

また、Where()メソッドのオーバーロードを使用して、Func引数に一致するどんなメソッドも呼び出すことができます。

public static void Main()
{
    var filteredResult = from s in studentList
                         where isTeenAger(s)
                         select s;
}
public static bool IsTeenAger(Student stud)
{
    return stud.Age > 12 && stud.Age < 20;  
}

メソッド記法のwhere拡張メソッド

クエリ記法とは異なり、整个のラムダ式をパターン関数として渡す必要があります。LINQメソッド記法の式本体のみを渡す必要はありません。

var filteredResult = studentList.Where(s => s.Age > 12 && s.Age < 20);
Dim filteredResult = studentList.Where(Function(s) s.Age > 12 And s.Age < 20 )

上記のように、Where拡張メソッドには、集合内の現在の要素のインデックスを含む第二重载もあります。必要に応じて、ロジックでそのインデックスを使用できます。

以下の例では、Where子句を使用して集合から奇数要素をフィルタリングし、偶数要素のみを返します。インデックスは0から始まることを忘れないでください。

IList<Student> studentList = new List<Student>() { 
        new Student() { StudentID = 1, StudentName = "John", Age = 18 }
        new Student() { StudentID = 2, StudentName = "Steve",  Age = 15 }
        new Student() { StudentID = 3, StudentName = "Bill",  Age = 25 }
        new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 },
        new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 } 
    };
var filteredResult = studentList.Where((s, i) => { 
            if(i % 2 == 0) // もし偶数なら
                return true;
                
        return false;
    });
foreach (var std in filteredResult)
        Console.WriteLine(std.StudentName);

 

出力:
John
Bill
Ron

複数のwhere子句

Where() 拡張メソッドを単一のLINQ検索で複数回呼び出すことができます。

例:C#のクエリ構文での複数のwhere子句
var filteredResult = from s in studentList
                        where s.Age > 12                    
                        where s.Age < 20                    
                        select s;
例:C#のメソッド構文での複数のwhere子句
var filteredResult = studentList.Where(s => s.Age > 12).Where(s => s.Age < 20);

  覚えておくべきポイント

  1. Where 指定された基準に基づいて集合をフィルタリングするために使用されます。

  2. その中で拡張メソッドには2つのオーバーロードメソッドがあります。2番目のオーバーロードメソッドを使用すると、集合内の現在の要素のインデックスを知ることができます。

  3. メソッド構文はWhere拡張メソッド内の整个lambda表現式が必要ですが、検索構文は表現体のみが必要です。

  4. 単一のLINQ検索で、複数のWhere拡張メソッドは有効です。