Select()和SelectMany()的區別


Select與SelectMany的區別

Select() 和 SelectMany() 的工作都是依據源值生成一個或多個結果值。

 

Select() 為每個源值生成一個結果值。因此,總體結果是一個與源集合具有相同元素數目的集合。與之相反,SelectMany() 將生成單一總體結果,其中包含來自每個源值的串聯子集合。作為參數傳遞到 SelectMany() 的轉換函數必須為每個源值返回一個可枚舉值序列。然后,SelectMany() 將串聯這些可枚舉序列以創建一個大的序列。

 

string[] text ={ "Albert was here", "Burke slept late", "Connor is happy" };  

var tokens = text.Select(s => s.Split(''));

 foreach (string[] line in tokens)

      foreach (string token in line)        

      Console.Write("{0}.", token);


 
string[] text ={ "Albert was here", "Burke slept late", "Connor is happy" };  
var tokens = text.SelectMany(s => s.Split(''));  

foreach (string token in tokens)    

  Console.Write("{0}.", token);

 

 

下面兩個插圖演示了這兩個方法的操作之間的概念性區別。在每種情況下,假定選擇器(轉換)函數從每個源值中選擇一個由花卉數據組成的數組。

下圖描述 Select() 如何返回一個與源集合具有相同元素數目的集合。

Select() 的操作的概念圖

下圖描述 SelectMany() 如何將中間數組序列串聯為一個最終結果值,其中包含每個中間數組中的每個值。

顯示 SelectMany() 的操作的圖。

 

CSDN的例子:

class Bouquet
{
    public List<string> Flowers { get; set; }
}

static void SelectVsSelectMany()
{
    List<Bouquet> bouquets = new List<Bouquet>() {
        new Bouquet { Flowers = new List<string> { "sunflower", "daisy", "daffodil", "larkspur" }},
        new Bouquet{ Flowers = new List<string> { "tulip", "rose", "orchid" }},
        new Bouquet{ Flowers = new List<string> { "gladiolis", "lily", "snapdragon", "aster", "protea" }},
        new Bouquet{ Flowers = new List<string> { "larkspur", "lilac", "iris", "dahlia" }}
    };

    // *********** Select ***********            
    IEnumerable<List<string>> query1 = bouquets.Select(bq => bq.Flowers);

    // ********* SelectMany *********
    IEnumerable<string> query2 = bouquets.SelectMany(bq => bq.Flowers);

    Console.WriteLine("Results by using Select():");
    // Note the extra foreach loop here.
    foreach (IEnumerable<String> collection in query1)
        foreach (string item in collection)
            Console.WriteLine(item);

    Console.WriteLine("\nResults by using SelectMany():");
    foreach (string item in query2)
        Console.WriteLine(item);

    /* This code produces the following output:

       Results by using Select():
        sunflower
        daisy
        daffodil
        larkspur
        tulip
        rose
        orchid
        gladiolis
        lily
        snapdragon
        aster
        protea
        larkspur
        lilac
        iris
        dahlia

       Results by using SelectMany():
        sunflower
        daisy
        daffodil
        larkspur
        tulip
        rose
        orchid
        gladiolis
        lily
        snapdragon
        aster
        protea
        larkspur
        lilac
        iris
        dahlia
    */

}

   Select() 和 SelectMany() 的工作都是依據源值生成一個或多個結果值。 Select() 為每個源值生成一個結果值。 因此,總體結果是一個與源集合具有相同元素數目的集合。 與之相反,SelectMany() 將生成單一總體結果,其中包含來自每個源值的串聯子集合。

  SelectMany()生成的是單一的總體結果。請看SelectMany()函數的實現形式:

 

 public static IEnumerable<TResult> SelectMany<TSource, TResult>(this IEnumerable<TSource> source,
Func<TSource, IEnumerable<TResult>> selector) { if (source == null) throw Error.ArgumentNull("source"); if (selector == null) throw Error.ArgumentNull("selector"); return SelectManyIterator<TSource, TResult>(source, selector); } static IEnumerable<TResult> SelectManyIterator<TSource, TResult>(IEnumerable<TSource> source,
Func<TSource, IEnumerable<TResult>> selector) { foreach (TSource element in source) { foreach (TResult subElement in selector(element)) { yield return subElement; } } }

 

在代碼中的紅色部分,可以看出SelectMany()的實現過程。在第一個例子中的SelectMany()。

            string[] text ={ "Albert was here", "Burke slept late", "Connor is happy" }; 
            var tokens = text.SelectMany(s => s.Split('')); 

            text.SelectMany(s => s.Split(''));      

可以用SelectManyIterator<TSource, TResult>(IEnumerable<TSource> source,Func<TSource, IEnumerable<TResult>> selector)替換,變成 SelectManyIterator(text,s=>s.Splt(' '));而在SelectManyIterator內部的代碼相應的變為:

               foreach (string element in text) {                            text是string[]數組 

                    foreach (string subElement in s=>s.Split(' ')) {               s.Split(' ')則編程text元素生成的可枚舉數組序列,IEnumerable<string>
                                yield return subElement;}}

以上轉換可以看下圖:

上圖中selector是Func<TSource,IEnumerable<TResult>>謂語表達式,相當於委托。示例中委托的又來克看下圖。

以上是我對Select()和SelectMany()的理解,如有錯誤歡迎指正:

參看CSDN的例子。網址:http://msdn.microsoft.com/zh-cn/library/bb546168.aspx#Mtps_DropDownFilterText

博主:itjeff ,網址:http://www.cnblogs.com/itjeff/p/3368627.html

itjeff

itjeff

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM