zoukankan      html  css  js  c++  java
  • 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("
    Results 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

  • 相关阅读:
    自制电脑红外遥控接收器(PC软解码) 转
    .NET Micro Framework介绍
    如何测试移动web?
    自行开发高效精简的二进制序列化库(支持精简框架集) 转
    35个优秀的电子商务网站界面
    .Net Micro Framework中的线程
    《肖申克的救赎》 阅后小记
    分享 MSDN 下载工具(Word/PDF)
    OEA ORM中的分页支持
    OEA 中的多国语言实现
  • 原文地址:https://www.cnblogs.com/zhangyuanbo12358/p/4107882.html
Copyright © 2011-2022 走看看