Linq 虽然用得多,但是里面有一些方法比较少用,因此整理一下。Enumerable 类的所有方法可以在 MSDN 上查阅到:https://msdn.microsoft.com/zh-cn/library/system.linq.enumerable.aspx

Aggregate

这个方法有三个重载,先看第一个

Aggregate<TSource>(IEnumerable<TSource>, Func<TSource, TSource, TSource>)

参数是接受两个 TSource 类型的输入,返回一个 TSource 类型的输出。

按照 MSDN 上的说明,输入的第一个参数是累加的值,第二个参数是元素。

{int[] array = new[] { 1, 2, 3, 4, 5 };int result = array.Aggregate((sum, i) => sum + i);Console.WriteLine(result);
}
{string[] array = new string[] { "hello", "world", "!" };string result = array.Aggregate((combine, str) =>{return combine + " " + str;});Console.WriteLine(result);
}

则会输出 15 和 hello world !

在第一次进入 Aggregate 的 Func 时,combine 的值为第一个元素的值,str 为第二个元素的值。

当输入的序列的元素个数为 0 时,则抛出 InvalidOperationException 异常。

而当元素的个数只有一个的时候,则不会执行 Func。

接下来看第二个重载

Aggregate<TSource, TAccumulate>(IEnumerable<TSource>, TAccumulate, Func<TAccumulate, TSource, TAccumulate>)

比起第一个重载,多了一个参数输入参数 TAccumulate,泛型参数也变成了两个。

{int[] array = new[] { 1, 2, 3, 4, 5 };long result = array.Aggregate(-1L, (sum, i) =>{return sum + i;});Console.WriteLine(result);
}

那么这段代码的输出则会是 14。第一次进入 Func 的时候,sum 的值为 -1L,i 的值是 1,这个行为跟第一个重载稍微有点区别。

而且当元素只有一个的时候,也是会进入 Func 的

当序列为空的时候,也不会触发到异常

直接等于输入参数的值。

第三个重载

Aggregate<TSource, TAccumulate, TResult>(IEnumerable<TSource>, TAccumulate, Func<TAccumulate, TSource, TAccumulate>, Func<TAccumulate, TResult>)

这个其实就是相当与第二个重载增加了最后一个参数

{string[] array = new string[] { "hello", "world", "!" };string result = array.Aggregate("start", (combine, str) =>{return combine + " " + str;}, end => end.ToUpperInvariant());Console.WriteLine(result);
}

执行后会输出 START HELLO WORLD !。

最后的那个参数相对于对最终结果进行了一下处理,跟下面的代码是等价的。

{string[] array = new string[] { "hello", "world", "!" };string result = array.Aggregate("start", (combine, str) =>{return combine + " " + str;}).ToUpperInvariant();Console.WriteLine(result);
}

DefaultIfEmpty

第一个重载

DefaultIfEmpty<TSource>(IEnumerable<TSource>)

就是说,如果一个序列的元素个数是零个的话,那就返回一个只有一个 default(TSource) 元素的序列。感觉这没啥用(lll¬ω¬)

看另一个重载

DefaultIfEmpty<TSource>(IEnumerable<TSource>, TSource)

多了个参数,猜也猜得出来了

唔,好像还是没啥实用意义…………

Except

Except<TSource>(IEnumerable<TSource>, IEnumerable<TSource>)

求差集

A 序列减去 B 序列,并且去重了。

另一重载

Except<TSource>(IEnumerable<TSource>, IEnumerable<TSource>, IEqualityComparer<TSource>)

多了一个比较器

最后只会输出 Hello,因为在 IgnoreCase 比较器下,world 和 WORLD 是一样的。

GroupBy

虽然用得还是比较多,但是重载比较多,还是写一下吧。

GroupBy<TSource, TKey>(IEnumerable<TSource>, Func<TSource, TKey>)

这个是最简单的重载了。

根据 Age 分组,这个重载很简单,也是最常用的。

GroupBy<TSource, TKey>(IEnumerable<TSource>, Func<TSource, TKey>, IEqualityComparer<TKey>)

多了一个比较器,不难

Key 会根据第一次匹配到的值。

GroupBy<TSource, TKey, TElement>(IEnumerable<TSource>, Func<TSource, TKey>, Func<TSource, TElement>)

第一个重载的改版而且,如果将上面的 person => person.Name 改为 person => person,那跟第一个重载没区别。

GroupBy<TSource, TKey, TElement>(IEnumerable<TSource>, Func<TSource, TKey>, Func<TSource, TElement>, IEqualityComparer<TKey>)

多了一个比较器而已,不说了。

GroupBy<TSource, TKey, TResult>(IEnumerable<TSource>, Func<TSource, TKey>, Func<TKey, IEnumerable<TSource>, TResult>)

分完组后对每一组进行了一下处理。

GroupBy<TSource, TKey, TResult>(IEnumerable<TSource>, Func<TSource, TKey>, Func<TKey, IEnumerable<TSource>, TResult>, IEqualityComparer<TKey>)

比上面多了一个比较器,不说了。

GroupBy<TSource, TKey, TElement, TResult>(IEnumerable<TSource>, Func<TSource, TKey>, Func<TSource, TElement>, Func<TKey, IEnumerable<TElement>, TResult>)

多了元素选择的参数重载,参考上面。

GroupBy<TSource, TKey, TElement, TResult>(IEnumerable<TSource>, Func<TSource, TKey>, Func<TSource, TElement>, Func<TKey, IEnumerable<TElement>, TResult>, IEqualityComparer<TKey>)

多了选择器,不说。

Join

Join<TOuter, TInner, TKey, TResult>(IEnumerable<TOuter>, IEnumerable<TInner>, Func<TOuter, TKey>, Func<TInner, TKey>, Func<TOuter, TInner, TResult>)

这个其实不难,只要参考一下 SQL 中的 inner join 的话。

先初始化测试数据

List<Person> list1 = new List<Person>()
{new Person(){Id = 1,Gender = "M"},new Person(){Id = 2 ,Gender = "F"},new Person(){Id = 3,Gender = "M"}
};
List<Student> list2 = new List<Student>()
{new Student(){Id = 1,Name = "martin"},new Student(){Id = 2,Name = "valid void"},new Student(){Id = 4,Name = "justin"}
};

然后测试代码走起

没啥难的,等价于以下的 linq 写法

Join<TOuter, TInner, TKey, TResult>(IEnumerable<TOuter>, IEnumerable<TInner>, Func<TOuter, TKey>, Func<TInner, TKey>, Func<TOuter, TInner, TResult>, IEqualityComparer<TKey>)

多了个比较器,用于比较 key,不说了。

GroupJoin

GroupJoin<TOuter, TInner, TKey, TResult>(IEnumerable<TOuter>, IEnumerable<TInner>, Func<TOuter, TKey>, Func<TInner, TKey>, Func<TOuter, IEnumerable<TInner>, TResult>)

看上去很复杂,但其实可以参考 Join 的输入进行对比。

测试数据我们还是沿用 Join 的。执行测试代码

对等的 linq 写法如下

var result = (from person in list1join student in list2 on person.Id equals student.Id into studentGroupselect new{Id = person.Id,Gender = person.Gender,Students = studentGroup.ToList()}).ToList();

GroupJoin<TOuter, TInner, TKey, TResult>(IEnumerable<TOuter>, IEnumerable<TInner>, Func<TOuter, TKey>, Func<TInner, TKey>, Func<TOuter, IEnumerable<TInner>, TResult>, IEqualityComparer<TKey>)

多了一个比较器,不说了。

SelectMany

这个最近这段时间用得比较多,也记录一下吧

SelectMany<TSource, TResult>(IEnumerable<TSource>, Func<TSource, IEnumerable<TResult>>)

测试代码

简单的来说就是将一个 IEnumerable<IEnumerable<T>> 的序列变成一个 IEnumerable<T> 的序列。

对等的 linq 写法

感觉 linq 写法会相对比较好理解的说。

SelectMany<TSource, TResult>(IEnumerable<TSource>, Func<TSource, Int32, IEnumerable<TResult>>)

Func 多了个 Int32 的参数,看测试代码

很好理解,就是当前的索引。

SelectMany<TSource, TCollection, TResult>(IEnumerable<TSource>, Func<TSource, IEnumerable<TCollection>>, Func<TSource, TCollection, TResult>)

比起第一个就是多了个结果执行而已

会进入这个 Func 四次,前两次是 helloword 那个 List,后两次是 justin martin 那个 List。

SelectMany<TSource, TCollection, TResult>(IEnumerable<TSource>, Func<TSource, Int32, IEnumerable<TCollection>>, Func<TSource, TCollection, TResult>)

多了索引,参考上面。

SequenceEqual

序列比较,知道有这个东西,但平时好像没有怎么用过。

SequenceEqual<TSource>(IEnumerable<TSource>, IEnumerable<TSource>)

很好理解,首要前提肯定是元素个数相等,其次要每一个元素相等。

SequenceEqual<TSource>(IEnumerable<TSource>, IEnumerable<TSource>, IEqualityComparer<TSource>)

多了个比较器,不说了。

SkipWhile

Skip 倒是一直在用,SkipWhile 就用得比较少,也记录一下吧。

SkipWhile<TSource>(IEnumerable<TSource>, Func<TSource, Boolean>)

不难,就是当 Func 返回 false 时停止。

因为当去到 3 的时候为 false,因此返回 3 和剩下的元素。

SkipWhile<TSource>(IEnumerable<TSource>, Func<TSource, Int32, Boolean>)

多了个索引而已,没啥好说的。

ToDictionary

先看第一个重载

ToDictionary<TSource, TKey>(IEnumerable<TSource>, Func<TSource, TKey>)

不难,Func 就是获取按照什么来生成 Key。

另外使用这个方法是要注意,Key 是不能重复的。

所以说实话,这方法平时比较少用。。。

ToDictionary<TSource, TKey>(IEnumerable<TSource>, Func<TSource, TKey>, IEqualityComparer<TKey>)

多了一个比较器,没啥好说的。

ToDictionary<TSource, TKey, TElement>(IEnumerable<TSource>, Func<TSource, TKey>, Func<TSource, TElement>)

比起第一个重载,多了一个如何生成字典的值的 Func,也没啥好说的。

ToDictionary<TSource, TKey, TElement>(IEnumerable<TSource>, Func<TSource, TKey>, Func<TSource, TElement>, IEqualityComparer<TKey>)

多了比较器,不说了。

ToLookup

这个有点像上面的 ToDictionary 的。

ToLookup<TSource, TKey>(IEnumerable<TSource>, Func<TSource, TKey>)

跟 ToDictionary 的第一个重载的输入参数是一样的。

ILookup<int, Person> 这个的结构类似于一个数组,然后每个数组的元素是一个 Group。

当元素的 Key 重复的时候:

那么这个 lookup 就只有一个 group 了,但这个 group 就会有多个元素。

ToLookup<TSource, TKey>(IEnumerable<TSource>, Func<TSource, TKey>, IEqualityComparer<TKey>)

ToLookup<TSource, TKey, TElement>(IEnumerable<TSource>, Func<TSource, TKey>, Func<TSource, TElement>)

ToLookup<TSource, TKey, TElement>(IEnumerable<TSource>, Func<TSource, TKey>, Func<TSource, TElement>, IEqualityComparer<TKey>)

这三个重载可以参考一下 ToDictionary 的重载,一样的说。

Zip

这个方法就只有一个,没别的重载

Zip<TFirst, TSecond, TResult>(IEnumerable<TFirst>, IEnumerable<TSecond>, Func<TFirst, TSecond, TResult>)

这里就借用 MSDN 上的示例代码了,看结果也看得出 Zip 这个操作的逻辑了。遍历两个序列进行操作,直到其中一个到达尾部。

另外像 TakeWhile 可以参考上面的 SkipWhile 就不说了。Distinct、Union 和 Intersect 平时也用得比较多,因此也不说了。

转载于:https://www.cnblogs.com/cjm123/p/8842705.html

整理一下 System.Linq.Enumerable 类中的那些比较少用的方法相关推荐

  1. (17)System Verilog禁止类中所有变量随机属性

    (17)System Verilog禁止类中所有变量随机属性 1.1 目录 1)目录 2)FPGA简介 3)System Verilog简介 4)System Verilog禁止类中所有变量随机属性 ...

  2. (16)System Verilog禁止类中所有变量随机化

    (16)System Verilog禁止类中所有变量随机化 1.1 目录 1)目录 2)FPGA简介 3)System Verilog简介 4)System Verilog禁止类中所有变量随机化 5) ...

  3. 2.在某应用软件中需要记录业务方法的调用日志,在不修改现有业务类的基础上为每一个类提供一个日志记录代理类,在代理类中输出日志,例如在业务方法 method() 调用之前输出“方法 method() 被

    2.在某应用软件中需要记录业务方法的调用日志,在不修改现有业务类的基础上为每一个类提供一个日志记录代理类,在代理类中输出日志,例如在业务方法 method() 调用之前输出"方法 metho ...

  4. 在Action类中获得HttpServletResponse对象的四种方法

    Struts2:在Action类中获得HttpServletResponse对象的四种方法 在struts1.x Action类的execute方法中,有四个参数,其中两个就是response和req ...

  5. Struts2教程6:在Action类中获得HttpServletResponse对象的四种方法

    在struts1.x Action类的execute方法中,有四个参数,其中两个就是response和request.而在Struts2中,并没有任何参数,因此,就不能简单地从execute方法获得H ...

  6. 谈谈Runtime类中的freeMemory,totalMemory,maxMemory几个方法

    最近在网上看到一些人讨论到java.lang.Runtime类中的freeMemory(),totalMemory(),maxMemory ()这几个方法的一些问题,很多人感到很疑惑,为什么,在jav ...

  7. spring aop如何在切面类中获取切入点相关方法的参数、方法名、返回值、异常等信息

    aop思想可以很好的帮助我们实现代码的解耦,比如我们之前提到的,将日志代码与业务层代码完全独立,通过spring aop的代理类进行整合.在切面类中,我们也能够通过spring提供的接口,很好的获取原 ...

  8. 枚举类中获取枚举值的几种方法

    在开发的过程中我们经常会定义枚举类,枚举类中获取枚举值的方式也有很多种,下面我们就探究一下大家常用的几种方式: 枚举类 public enum TestEnum {ONE(1,"one&qu ...

  9. 【Groovy】Groovy 脚本调用 ( Groovy 类中调用 Groovy 脚本 | 参考 Script#evaluate 方法 | 创建 Binding 对象并设置 args 参数 )

    文章目录 一.Groovy 类中调用 Groovy 脚本 1.参考 Script#evaluate 方法分析 Groovy 类中调用 Groovy 脚本 2.创建 Binding 对象并设置 args ...

最新文章

  1. 矩阵乘法的性能提升 AutoKernel
  2. 不用在读长和准确性之间做选择题,PacBio发表新方法
  3. SQL Server遍历表的几种方法
  4. 使用Q进行同步的Promises操作
  5. 算法提高 日期计算c语言,算法提高 日期计算
  6. 【ES6(2015)】Map
  7. 数据产品-短视频评估体系构建
  8. BGP/MPLS *** Option B 跨域研究实验
  9. html中md5如何使用方法,html中使用js進行登錄md5加密提交並重定向新頁面
  10. 计算机硬件系统设计原理 pdf,C1-1计算机硬件系统设计.pdf
  11. 禅道服务器修改ip,访问禅道服务器的ip地址
  12. P18利用5次shift漏洞破解win7密码
  13. 微信小程序请求java后台 springmvc 获取json
  14. 开源项目-CRM客户关系管理系统
  15. nagios之nsca被动监控
  16. 计算机二级的Word知识点,计算机等级考试二级office基础知识点总结.doc
  17. GBK编码和UTF-8编码的区别
  18. C++ 定义盒子的Box类,具有以下要求: 可设置盒子的形状; 可计算盒子的体积; 可计算盒子的表面积
  19. Android eclipse 程序调试
  20. autojs 简单使用

热门文章

  1. CSS---复合选择器
  2. 【Qt学习】 登录验证 注册 功能实现
  3. 1字节(Byte)的范围及转换
  4. android电脑不识别手机号码,安卓手机刷机后电脑不识别怎么办 如何让电脑重新识别手机...
  5. Spark GraphX 中的 pregel 算法
  6. CentOS6.5系统光纤连接存储的多路径配置及使用方法
  7. MySQL—数据处理之增删改查(四)
  8. 虚拟机网络、联网设置、与宿主机互联、网络配置
  9. 判了!40岁程序员被判7年,曾提出系统安全问题被无视,怒删9TB财务数据及系统数据!...
  10. 飞机大战(easyx版)