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() 如何返回一個與源集合具有相同元素數目的集合。

下圖描述 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