Linq的出现让代码简洁了不少。之前在项目中基本都在使用它,但是没有完整的整理过,今天借这个周末,将其进行整理,方便后期对其的使用。Linq的操作可以分为聚合,连接,转换,元素操作符,相等操作,生成,分组,分部,投影,数量,过滤,排序等,下面我们就通过实例的方式一一说下。

在具体实例之前先定义两个集合供下面的使用和封装的三个控制台输出方法:

         List<string> words = new List<string>() { "zero", "one", "two", "three", "four" };
List<int> numbers = new List<int>() { , , , , };

  

   static void Write(string name, object obj)
{
Console.WriteLine($"method:{name},\t result:{obj.ToString()}");
} static void Write(string title)
{
Console.WriteLine($"---------{title}-------------");
} static void Write()
{
Console.WriteLine($"-------------------------------");
}

聚合

最常见的聚合操作符就是Aggregate,所有的其他聚合操作符都能表示为对Aggregate的调用,所有聚合操作符都使用立即执行的模式

             Write("聚合操作");
int sum = numbers.Sum();
Write("sum", sum);
int count = numbers.Count;
Write("count", count);
double average = numbers.Average();
Write("average", average);
long longCount = numbers.LongCount(x => x % == );
Write("longCount", longCount);
int min = words.Min(p => p.Length);
Write("min", min);
int max = words.Max(p => p.Length);
Write("max", max);
string aggregate = numbers.Aggregate("seed", (current, item) => current + item, result => result.ToUpper());
Write("aggregate", aggregate);
Write();

结果:

连接

         Write("连接");
List<int> concat = numbers.Concat(new List<int>() { , , , , }).ToList();
Write("concat", string.Join(",", concat));
Write();

结果:

转换

toArray和toList的含义显而易见,他们读取整个序列到内存中,并把结果作为一个数组或一个List<T>返回。两者都是立即执行,cast和ofType把一个非类型化序列转换为类型化序列的,或抛出异常(对于cast),或忽略那些不能隐式转换为序列元素类型的输入序列元素(对于ofType),这个运算符也能用于把某个类型化序列转换为更加具体的类型化序列。转换以流的形式延迟执行。ToDictionary和TolookUp都使用委托来获得任何特定元素的键。执行模式为立即执行

             Write("转换");
List<Object> allString = new List<Object>() { "These", "are", "all", "strings" };
List<Object> notAllString = new List<Object>() { "Number", "at", "the", "end", }; IEnumerable<string> castOne = allString.Cast<string>();
Write("castOne", string.Join(",", castOne));
IEnumerable<string> ofTypeOne = allString.OfType<string>();
Write("ofTypeOne", string.Join(",", ofTypeOne)); IEnumerable<string> castTwo = notAllString.Cast<string>();
Write("castOne", string.Join(",", castTwo));//遍历时遇到转换失败的地方,会抛出异常
IEnumerable<string> ofTypeTwo = notAllString.OfType<string>();
Write("ofTypeOne", string.Join(",", ofTypeTwo)); int[] toArray = numbers.ToArray();
List<int> toList = numbers.ToList(); Dictionary<string, string> dictionary = words.ToDictionary(w => w.Substring(, ));
ILookup<char, string> toLookUp = words.ToLookup(word => word[]); IDictionary<char, string> toDictionary = words.ToDictionary(p => p[]);//异常:每个键只能有一个数据项,所以与遇到‘t’时转换会异常 Write();

元素操作符

每个操作符都以同样的方式执行,选取单个元素的简化版本,就是在特定元素存在时返回他,不存在时就抛出一个异常,还有一个以orDefault结尾的版本,orDefault版本的功能完全一样,只是在找不到想要的元素是,返回结果类型的默认值,而非抛出异常,但是有一种例外,如果序列为空,singleDefault将返回默认值,但是如果序列中的元素不止一个,将抛出异常,就像Single一样.。所有操作符都是使用立即执行模式

             var elementAt = words.ElementAt();//"Two"
var elementAtOrDefault = words.ElementAtOrDefault();//Null
var first = words.First();//Zero
var firstTwo = words.First(p => p.Length == );//one
// var firstThree = words.First(p=>p.Length==10);//异常
var firstOrDefault = words.FirstOrDefault(p => p.Length == );//Null
var last = words.Last();//four
var single = words.Single();//异常,不止一个元素
var singleDefault = words.SingleOrDefault();//异常,不止一个元素
var singleTwo = words.Single(p => p.Length == );//three
var singleThree = words.Single(p => p.Length == );//异常,没有匹配的元素
var singleDefaultTwo = words.SingleOrDefault(P => P.Length == );//Nul

相等操作

   按照顺序逐一比较两个序列中的元素是否相等,执行模式为立即执行

  bool sequenceEqual = words.SequenceEqual(new List<string>() { "zero", "one", "two", "three", "four" });//true
bool sequenceEqualTwo = words.SequenceEqual(new List<string>() { "ZERO", "OME", "TWO", "THREE", "FOUR" });//false
bool sequenceEqualThree = words.SequenceEqual(new List<string>() { "ZERO", "OME", "TWO", "THREE", "FOUR" }, StringComparer.OrdinalIgnoreCase);//true

生成

  在所有的生成操作符中,只有一个会对现有的序列进行处理:DefaultIfEmpty.如果序列不为空,就返回原始序列,否则返回含有但非我元素的序列。其中的元素通常是序列类型的默认值,不过重载方法允许你设定要使用的值.所有生成的操作符都是用延迟执行,并对结果进行流式处理。也就是说,他们不会预先生成集合并返回。不过,返回正确类型的空数组的empty方法是个例外。一个空的数组是完全不可变的,因此相同元素类型的所有元素类型的所有这种调用,都将返回相同的空数组。

        var defaultIfEmpty = numbers.DefaultIfEmpty();//0,1,2,3,4
var defaultIfEmptyTwo = new int[].DefaultIfEmpty();//
var defaultIfEmptyThree = new int[].DefaultIfEmpty();//
var range = Enumerable.Range(, );//15,16
var repeat = Enumerable.Repeat(, );//25,25
IEnumerable<int> empty = Enumerable.Empty<int>();//一个类型为IEnumerable<int>的空序列

分组

             IEnumerable<IGrouping<int, string>> groupby = words.GroupBy(p => p.Length);
IEnumerable<IGrouping<int, string>> groupTwo = words.GroupBy(p => p.Length, p => p.ToUpper());
IEnumerable<string> groupThree = words.GroupBy(p => p.Length, (key, g) => key + ":" + g.Count());

结果:

投影

   Select是一种简单的从源元素到结果元素的一对一投影,selectMany在查询表达式中有多个from子句的时候使用;原始序列中的每个元素都用来生成新的序列。两个投影都是

延迟执行,.net 4 引入了一个新的操作符zip。它包含两个序列,并对每个元素对应用指定的投影:先是每个序列的第一个元素,然后是每个序列的第二个元素,以此类推

任何一个源序列达到末尾时,结果序列都将停止产生。

             IEnumerable<int> selectOne = words.Select(p => p.Length);//4,3,3,5,4
IEnumerable<string> selectTwo = words.Select((word, index) => index.ToString() + ":" + word);//0:zero,1:one ....
IEnumerable<char> selectMany = words.SelectMany(p => p.ToCharArray());//z,e,r,o,o...
IEnumerable<string> selectManyTwo = words.SelectMany((word, index) => Enumerable.Repeat(word, index));
5 IEnumerable<string> zip = names.Zip(colors, (x, y) => x + "-" + y);

数量

数量操作符都返回一个boolean值,使用立即执行

             bool allOne = words.All(p => p.Length > );//false
bool allTwo = words.All(p => p.Length > );//true
bool any = words.Any();//true
bool anyTwo = words.Any(p => p.Length == );//false
bool antThree = words.Any(p => p.Length == );//true
bool contains = words.Contains("FOUR");//false
bool containsTwo = words.Contains("FOUR", StringComparer.OrdinalIgnoreCase);//true

过滤

两个过滤操作符where和ofType。where返回一个序列,where总是使用延迟执行和流式数据。

         IEnumerable<string> where = words.Where(p => p.Length > );//zero,three,four
IEnumerable<string> whereTwo = words.Where((word, index) => index < word.Length);//one,two,three

基于集的操作符

    把两个序列作为元素的集合是很自然的。4个基于几何的运算符都具有两个重载方法,一个使用元素类型的默认相等比较,一个用于额外的参数中指定比较。所有的集合运算符都是延迟执行的

         List<string> abbc = new List<string>() { "a", "b", "b", "c" };
List<string> cd = new List<string>() { "c", "d" }; var distinct = abbc.Distinct();//a,b,c
var intersect = abbc.Intersect(cd);//c 交集
var union = abbc.Union(cd);//a,b,c,d //并集
var expect = abbc.Except(cd);//a,b //差集
var exceptTwo = cd.Except(abbc);//d

排序

    orderBy和OrderByDescending提供了主要的排序方式,thenBy 和ThenByDescending提供了次要排序方式。用以区别使用主要的排序方式无法区别的元素。在每种情况中,都要指定从元素到排序键的投影,也指定键之间的比较。linq排序比较稳定,即如果两个元素根据他们的排序关键字被认为相等,那么将按照他们原始序列中的顺序返回

             var orderBy = words.OrderBy(p => p);//four,one,three,two,zero
var orderByTwo = words.OrderBy(p => p[]);//zero,three,one,four,two
var orderByThree = words.OrderBy(p => p.Length);//one,two,zero,four,three
var orderByDescending = words.OrderByDescending(p => p.Length);//three,zero,four,one,two
var orderByFour = words.OrderBy(p => p.Length).ThenBy(p => p);//one,two,four,zero,three
var orderByFive = words.OrderBy(p => p.Length).ThenByDescending(p => p);//two,one,zero,four,three
words.Reverse();//four,three,two,one,zero

Linq标准查询操作符的更多相关文章

  1. Linq 标准查询操作符三

    本文介绍了LINQ标准查询操作符.没有这些操作符,LINQ就不会存在.本文为理解这些操作符的功能提供了很好的基础.了解它们将会很有帮助,因为LINQ的各种Provider都是基于这些操作符来完成各自丰 ...

  2. LINQ 标准查询操作符

    本文介绍了LINQ标准查询操作符.没有这些操作符,LINQ就不会存在.本文为理解这些操作符的功能提供了很好的基础.了解它们将会很有帮助,因为LINQ的各种Provider都是基于这些操作符来完成各自丰 ...

  3. LINQ标准查询操作符详解(转)

     一. 关于LINQ       LINQ 英文全称是“Language-Integrated Query”,中文为“语言集成查询”,它是微软首席架构师.Delphi 之父和C# 之父——Anders ...

  4. LINQ标准查询操作符(三)——Aggregate、Average、Distinct、Except、Intersect、Union、Empty、DefaultIfEmpty、Range、Repeat

    七.聚合操作符 聚合函数将在序列上执行特定的计算,并返回单个值,如计算给定序列平均值.最大值等.共有7种LINQ聚合查询操作符:Aggregate.Average.Count.LongCount.Ma ...

  5. 【LINQ标准查询操作符总结】之聚合操符

    C#  中的LINQ 提供了两种操作方式,查询表达式和查询操作符,所有的查询表达式都有对应的查操作符类替代,查询表达式有点“类” SQL,在代码中写SQL,总觉得不够“优雅”,使用查询操作符就显得“优 ...

  6. LINQ标准查询操作符(四) —AsEnumerable,Cast,OfType,ToArray,ToDictionary,ToList,ToLookup,First,Last,ElementAt

    十.转换操作符 转换操作符是用来实现将输入对象的类型转变为序列的功能.名称以“As”开头的转换方法可更改源集合的静态类型但不枚举(延迟加载)此源集合.名称以“To”开头的方法可枚举(即时加载)源集合并 ...

  7. LINQ标准查询操作符(五)

    十二.相等操作符 如果两个序列的对应元素相等且这两个序列具有相同数量的元素,则视这两个序列相等. SequenceEqual方法通过并行地枚举两个数据源并比较相应元素来判断两个序列是否相等.如果两个序 ...

  8. LINQ标准查询操作符(二)——Join、GroupJoin、GroupBy、Concat、

    四.联接操作符 联接是指将一个数据源对象与另一个数据源对象进行关联或者联合的操作.这两个数据源对象通过一个共同的值或者属性进行关联. LINQ有两个联接操作符:Join和GroupJoin. 1. J ...

  9. LINQ标准查询操作符(一)——select、SelectMany、Where、OrderBy、OrderByDescending、ThenBy、ThenByDescending和Reverse

    一.投影操作符 1. Select Select操作符对单个序列或集合中的值进行投影.下面的示例中使用select从序列中返回Employee表的所有列: //查询语法 var query = fro ...

随机推荐

  1. 201521123078《Java程序设计》第1周学习总结

    1. 本周学习总结 简单的了解JVM,JRE,JDK,编写简单的Java程序 2. 书面作业 为什么java程序可以跨平台运行?执行java程序的步骤是什么?(请用自己的语言书写) 通过JVM虚拟机, ...

  2. PHOTOSHOP常用快捷键大全

    PHOTOSHOP常用快捷键大全一.文件新建 CTRL+N打开 CTRL+O 打开为 ALT+CTRL+O关闭 CTRL+W保存 CTRL+S 另存为 CTRL+SHIFT+S另存为网页格式 CTRL ...

  3. Linux帮助手册(man)

    Linux的帮助文档 在我们使用Linux的过程中,都会遇到这样那样的问题,一般我们在计算机能连上网的情况下会进行百度或Google解决问题,但是并不是所有文题都能在网上很快得到答案.万一我们是在没有 ...

  4. Mybatis第八篇【一级缓存、二级缓存、与ehcache整合】

    Mybatis缓存 缓存的意义 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题. myba ...

  5. Android 之http编程

    HTTP-GET和HTTP-POST定义: 都是使用HTTP的标准协议动词,用于编码和传送变量名/变量值对参数,并且使用相关的请求语义. 每个HTTP-GET和HTTP-POST都由一系列HTTP请求 ...

  6. [android游戏开发初学]SurfaceView初探之缓冲区测试

    先上测试代码 private static class PathView extends SurfaceView implements SurfaceHolder.Callback{ private ...

  7. java 线程二

    一.线程的优先级别 线程优先级别的使用范例: 1 package cn.galc.test; 2 3 public class TestThread6 { 4 public static void m ...

  8. Redis学习——Redis持久化之RDB备份方式保存数据

    从这一个介绍里面知道,redis比memcache作为缓存数据库强大的地方,一个是支持的数据类型比较多,另一个就是redis持久化功能. 下面就介绍Redis的持久化之RDB! 一:什么是redis的 ...

  9. HDFS概述(1)————HDFS架构

    概述 Hadoop分布式文件系统(HDFS)是一种分布式文件系统,用于在普通商用硬件上运行.它与现有的分布式文件系统有许多相似之处.然而,与其他分布式文件系统的区别很大.HDFS具有高度的容错能力,旨 ...

  10. HDFS源码分析之NameNode(3)————RpcServer

    NameNodeRpcServer implements NamenodeProtocols NameNode支持核心即NameNodeRpcServer 实现ClientProtocol  支持客户 ...