Where的應用

Where這個語法對於大家來說應該都不陌生,要查詢的情境幾乎都脫離不了篩選資料的處理,Where在LINQ中就是篩選條件的語法,接下來請看Where的介紹。

功能說明

使用Where可以取得集合中符合描述的元素。

方法定義

Where的方法有兩個,差別依然是有沒有index傳入參數:

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);
  • predicate: 資料的描述,可以注意到回傳值是一個bool,代表predicate會是一個判斷式,符合的資料就放進集合中
  • Where方法有延遲執行的特性

我們來看看出自Microsoft Docs的例子:

linq_filter

我們有個sourcechar陣列,如上圖的Source,現在我想要拿出A的元素,我們會利用Where取得A的資料:

char[] source = new char[] { 'A', 'B', 'C', 'A', 'B', 'A', 'C' };

IEnumerable<char> result = source.Where(letter => letter == 'A');

// output: A A A
  • predicate是一個判斷式Lambda Expression

透過這個例子我們就可以清楚的了解Where就是為了篩選資料。

查詢運算式

C# Spec可以找到Where的定義:

where_clause
    : 'where' boolean_expression
    ;

我們可以看到where運算式後面是接判斷式,跟if一樣,如果是true就是符合的資料,反之是不符合的資料。

我們將剛剛在方法定義時使用的例子轉為運算式試試看:

from letter in source
where letter == 'A'
select letter;

// output: A A A

這邊有一點要注意的是where可以在一段運算式中的任何地方除了最前面(from)及最後面(select、group)

方法範例

多個條件的判斷式

取得AC的資料:

char[] source = new char[] { 'A', 'B', 'C', 'A', 'B', 'A', 'C' };

var result = 
    //source.Where(letter => letter == 'A' || letter == 'C');
    from letter in source
    where letter == 'A' || letter == 'C'
    select letter;

// output: A C A A C
  • ||(或)跟&&(且)來串接多個條件

利用index取得資料

排除index5的資料:

char[] source = new char[] { 'A', 'B', 'C', 'A', 'B', 'A', 'C' };

var result = source.Where((letter, index) => index != 5);

// output: A B C A B C
  • 查詢運算式不能使用index參數

使用函式當條件

取得A的資料:

char[] source = new char[] { 'A', 'B', 'C', 'A', 'B', 'A', 'C' };

IEnumerable<char> result =
    //source.Where(equalA);
    from letter in source
    where equalA(letter)
    select letter;

// output: A A A

private static  bool equalA(char letter)
{
    return letter == 'A';
}

結語

Where是一個篩選條件的方法,以predicate當作判斷式,如果符合判斷式則傳回此元素。

範例程式

GitHub

參考