iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 26
0
Software Development

深入探索LINQ系列 第 26

C#的利器LINQ-Take的應用

前面的Skip方法是在目標集合上做忽略元素的處理,這次要說的Take是跟Skip完全相反的方法,Take是做選取元素的處理,接下來我們來看看Take的使用方式。

功能說明

設定資料來源要選取的元素數或是條件後取得目標元素集合。

方法定義

Skip相同,Take也有三個不同名稱的方法: TakeTakeLastTakeWhile,現在依序來看他們的定義:

三個方法的比較圖如下:

https://ithelp.ithome.com.tw/upload/images/20180114/20107789BJ6eTD2lhy.png

  • Take: 第一個元素起算到參數設定的數量為止的元素的集合為結果集合
  • TakeLast: 最後個元素往前算到參數設定的數量為止的元素集合為結果集合
  • TakeWhile: 第一個元素開始取直到不符合條件的元素為止,結果集合為第一個元素到不符合條件的元素的前一個元素元素的集合

上面簡述了三個Take方法的元素取法,下面我們繼續介紹個別的方法定義。

Take

public static IEnumerable<TSource> Take<TSource>(
    this IEnumerable<TSource> source,
    int count);
  • count: 由第一個開始選取的元素數量

Take是由第一個元素選取count個元素的集合

TakeLast

public static IEnumerable<TSource> TakeLast<TSource>(
    this IEnumerable<TSource> source,
    int count);
  • count: 由最後一個往前選取的元素數量

TakeLast是由最後個元素往前選取count個元素的集合

TakeWhile

TakeWhile兩個公開方法,差別在predicate有沒有傳入index參數

public static IEnumerable<TSource> TakeWhile<TSource>(
    this IEnumerable<TSource> source,
    Func<TSource, bool> predicate);

public static IEnumerable<TSource> TakeWhile<TSource>(
    this IEnumerable<TSource> source,
    Func<TSource, int, bool> predicate);
  • predicate: 選取的條件,一旦碰到傳回false的元素,此元素(包含)後的所有元素都會被忽略

TakeWhile是由predicate判斷式來決定選取的元素,如果元素讓predicate傳回false,這個元素後的所有元素都會被忽略。

方法範例

顏色

以上圖的例子實作範例

string[] color = new string[] { "Orange", "Blue", "Yellow", "Green", "Pink" };

IEnumerable<string> skipResults = color.Take(3);
IEnumerable<string> skipLastResults = color.TakeLast(3);
IEnumerable<string> skipWhileResults = color.TakeWhile(x => x != "Yellow");

Dictionary<string, IEnumerable<string>> results = new Dictionary<string, IEnumerable<string>>(){
    { "Skip", skipResults },
    { "SkipLast", skipLastResults },
    { "SkipWhile", skipWhileResults }
};

string output = "";
foreach (KeyValuePair<string, IEnumerable<string>> keyValue in results)
{
    output += $"{keyValue.Key}: ";
    foreach (string c in keyValue.Value)
    {
        output += $"{c},";
    }
    output = output.Trim(',') + '\n';
}
Console.WriteLine(output);

輸出結果如下:

/*
 * Take: Orange,Blue,Yellow
 * TakeLast: Yellow,Green,Pink
 * TakeWhile: Orange,Blue
 */

特別之處

  • 延遲執行的特性,使用foreach或是叫用GetEnumerator()時才會對資料做處理
  • 沒有查詢運算式
  • TakeTakeLast指定的count數量大於集合數量,則傳回完整的集合
  • TakeTakeLast指定的count數量小於等於零,則傳回空的集合
  • TakeSkip互補的,以相同的條件叫用Skip(SkipLastSkipWhile)跟Take(TakeLastTakeWhile),兩個結果合在一起的元素集合會是原本的集合

結語

這次說的TakeSkip在很多方面是相同的,因這兩個方法互補,所以說明起來會跟Skip很相似,之後的原碼探索應該也會是這樣,我們到時再來瞧瞧。

範例程式

參考


上一篇
C#的利器LINQ-Skip的原碼探索
下一篇
C#的利器LINQ-Take的原碼探索
系列文
深入探索LINQ30

尚未有邦友留言

立即登入留言