1. OfType

   获取集合中中指定类型元素。

 object[] obj = { , , , , , "aaa", "bbb" };
int max = obj.OfType<int>().Max(); //结果是55, 获取int类型中的最大值

2. selectMany

  相当于二次遍历查找,先遍历一级出来item,再遍历二级item. 和Select的区别,Select只遍历一级。

            string[] text = { "Albert was here", "Burke slept late", "Connor is happy" };
var d1 = text.Select(s => s.Split(' ')).ToList(); //3个元素,每个元素里面又有3个
var d2 = text.SelectMany(s => s.Split(' ')).ToList(); //9个元素
var d3 = text.Select(s => s.ToString()).ToList(); //3个元素
var d4 = text.SelectMany(s => s.ToString()).ToList(); //45个元素,一个字母一个元素,空格也算
foreach (var item in d4)
{
Console.WriteLine(item);
}

3. GroupJoin

  类似sql中的左连接,linq中join-on-into, 注意:linq中的做外链接操控数据库和直接查出来的集合是不一样,参考集合select的时候要判空,详见下面代码。

代码分享:

   List<Person> pList = new List<Person>
{
new Person{ id = , pName = "ABC" },
new Person{ id = , pName = "EFG" },
new Person{ id = , pName = "HIJ"},
new Person{ id = , pName = "KLM"},
new Person{ id = , pName = "NOP" },
new Person{ id = , pName = "QRS"},
new Person{ id = , pName = "TUV"}
};
List<City> cList = new List<City>
{
new City{ id = ,cName = "Guangzhou",uId=},
new City{ id = ,cName = "Shenzhen",uId= },
new City{ id = ,cName = "Beijing" ,uId=},
new City{ id = ,cName = "Shanghai",uId= },
new City{ id = ,cName = "K4",uId= }
};
//3.1 先用linq实现一下左连接
////左外连接,需要对右表进行判空
////此处需要特别注意:这里是对应已经查出来的集合进行左外链接,所以需要对右表进行判空处理,如:cName = k == null ? "" : k.cName
////但是这里如果改成直接操作数据库,pList改为db.Person,cList改为db.City, 则无需对右表进行判空,因为它会生成标准left join的sql语句,操控数据库。
Console.WriteLine("------------------------下面是linq左连接查询--------------------------");
var result1 = from p in pList
join c in cList on p.id equals c.uId into fk
from k in fk.DefaultIfEmpty()
select new { p.id, p.pName, cName = k == null ? "" : k.cName };
var list1 = result1.ToList();
foreach (var item in list1)
{
Console.WriteLine($"UserId={item.id},Name={item.pName},CityName={item.cName}");
}
//3.2 重点GroupJoin用法 (等价于上面的左外连接)
Console.WriteLine("------------------------下面是GroupJoin左连接查询--------------------------");
var result2 = pList.AsQueryable().GroupJoin(cList, p => p.id, c => c.uId, (p, cs) => new
{
p.id,
p.pName,
cName = cs.Select(u => u.cName).ToList()
});
var list2 = result2.ToList();
foreach (var item in list2)
{
if (item.cName.Count() != )
{
foreach (var citem in item.cName)
{
Console.WriteLine($"CityID={item.id},Name={item.pName},CityName={citem}");
}
}
else
{
Console.WriteLine($"CityID={item.id},Name={item.pName},CityName=");
}
}

运行结果:

4. ToLookup

  当同一个key要求对应多个value情况ToLookup方法是非常有用的,ToLookup返回一种特殊的数据结构类似我们sql中的group.可以把集合分组并且可以用索引访问这些元素。

注意: Lookup,不像Dictionary, 是不可改变的。 这意味着一旦你创建一个lookup, 你不能对数据源添加或删除元素,即无效,GroupBy后是可以增删的

            var products = new List<Product>
{
new Product {pId = "", Category = "Electronics", Value = 15.0},
new Product {pId = "", Category = "Groceries", Value = 40.0},
new Product {pId = "", Category = "Garden", Value = 210.3},
new Product {pId = "", Category = "Pets", Value = 2.1},
new Product {pId = "", Category = "Electronics", Value = 19.95},
new Product {pId = "", Category = "Pets", Value = 21.25},
new Product {pId = "", Category = "Pets", Value = 5.50},
new Product {pId = "", Category = "Garden", Value = 13.0},
new Product {pId = "", Category = "Automotive", Value = 10.0},
new Product {pId = "", Category = "Electronics", Value = 250.0},
}; {
Console.WriteLine("使用ToLookup分组");
var groups = products.ToLookup(p => p.Category);
//删除所有属于Garden的产品(注意ToLookup删除无效哦)
products.RemoveAll(p => p.Category == "Garden");
foreach (var group in groups)
{
Console.WriteLine(group.Key);
foreach (var item in group)
{
Console.WriteLine($"pid={item.pId},Category={item.Category},Value={item.Value}");
}
}
}
{
Console.WriteLine("使用GroupBy分组");
var groups = products.GroupBy(p => p.Category);
//删除所有属于Garden的产品
products.RemoveAll(p => p.Category == "Garden");
foreach (var group in groups)
{
Console.WriteLine(group.Key);
foreach (var item in group)
{
Console.WriteLine($"pid={item.pId},Category={item.Category},Value={item.Value}");
}
}
}

运行结果:

5. AsEnumerable/AsQueryable/Cast

(1).AsEnumerable:是延迟执行的,实际上什么都没有发生,当真正使用对象的时候才执行.

(2).AsQueryable:也是延迟执行的,将一个序列向下转换为一个IQueryable, 它生成了一个本地查询的IQueryable包装.

下面看一下各自linq生成的SQL语句:

(3).Cast:将 IQueryable 的元素转换为指定的类型

            List<object> words = new List<object> { "green", "blue", "violet" };
var query1 = words.AsQueryable().Cast<string>().ToList(); //将object类型的list集合转换成string的list集合
//补充写法2
List<string> query = words.Select(u => (string)u).ToList(); //实际上遍历挨个转换

6. SequenceEqual

  比较list和list之间、数组和数组之间是否相等。

            string[] text1 = { "Albert was here", "Burke slept late", "Connor is happy" };
string[] text2 = { "Albert was here", "Burke slept late", "Connor is happy" };
string[] text3 = { "Albert was here", "Burke slept late", "Connor is happy111" };
string[] text4 = { "Albert was here", "Burke slept late" };
Console.WriteLine(text1.SequenceEqual(text2)); //true
Console.WriteLine(text2.SequenceEqual(text3)); //false
Console.WriteLine(text2.SequenceEqual(text4)); //false

7. DefaultIfEmpty

  返回指定序列的元素;如果序列为空,则返回单一实例集合中的类型参数的默认值。多用于外连接查询。

            int[] arr1 = { , , , , , , , ,  };//构造带元素的数组
int[] arr2 = { }; //构造一个空数组
string[] str = { };
var d1 = arr1.DefaultIfEmpty().ToList(); //9个元素
var d2 = arr2.DefaultIfEmpty().ToList(); //1个元素,且为0,即int类型的默认值
var d3 = arr2.DefaultIfEmpty().ToList(); //1个元素,且为86,即int类型的默认值
var d4 = str.DefaultIfEmpty().ToList(); //1个元素,且为null,即string类型的默认值

8. Empty

  内部生成了一个T[]数组,数组的个数为0。

            List<string> list1 = new List<string>();
var arry2 = Enumerable.Empty<string>(); //Enumerable.Empty<int>() 其实在内部生成了一个T[]数组,数组的个数为0。
foreach (var item in list1)
{
Console.WriteLine(item);
}
foreach (var item in arry2)
{
Console.WriteLine(item);
}

9. Range

  生成指定范围内的整数的序列。如下代码:

            var list = Enumerable.Range(, ).ToList();  //从10开始,依次添加100个整数,即 10-109
foreach (var item in list)
{
Console.WriteLine(item);
}

10.Repeat

  包含一个重复值的序列。

            var list = Enumerable.Repeat<int>(, ).ToList();   //生成100个10存放在集合中
foreach (var item in list)
{
Console.WriteLine(item);
}

11.Aggregate

  做一些复杂的聚合运算,例如累计求和,累计求乘积。它接受2个参数,一般第一个参数是称为累积数(默认情况下等于第一个值),而第二个代表了下一个值。第一次计算之后,计算的结果会替换掉第一个参数,继续参与下一次计算,第二个参数往后顺延。

            {
//11.1 累加和阶乘
int[] arry1 = { , , , , };
int result1 = arry1.Aggregate((a, b) =>
{
return a + b;
});
//执行的操作是: 1+2=3; 3+3=6; 6+4=10; 10+5=15;
Console.WriteLine($"累加的结果为:{result1}");
int result2 = arry1.Aggregate((a, b) =>
{
return a * b;
});
//执行的操作是: 1*2=2; 2*3=6; 6*4=24; 24*5=120;
Console.WriteLine($"阶乘的结果为:{result2}");
//11.2. 实现字符串翻转
string msg1 = "my name is ypf";
string[] arry3 = msg1.Split(' ');
string result3 = arry3.Aggregate((m, n) =>
{
return $"{n} {m}";
});
Console.WriteLine($"反转后的结果为:{result3}");
//11.3 求数组中比“banana”长度长的最长字符串
string[] fruits = { "apple", "mango", "orange", "passionfruit", "grape" };
// Determine whether any string in the array is longer than "banana".
string longestName = fruits.Aggregate("banana", (longest, next) =>
{
return next.Length > longest.Length ? next : longest;
}, fruit => fruit.ToLower()); Console.WriteLine("The fruit with the longest name is {0}.", longestName);
}

运行结果:

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 

第十六节:Linq用法大全(四)的更多相关文章

  1. 第四百一十六节,Tensorflow简介与安装

    第四百一十六节,Tensorflow简介与安装 TensorFlow是什么 Tensorflow是一个Google开发的第二代机器学习系统,克服了第一代系统DistBelief仅能开发神经网络算法.难 ...

  2. ASP.NET MVC深入浅出系列(持续更新) ORM系列之Entity FrameWork详解(持续更新) 第十六节:语法总结(3)(C#6.0和C#7.0新语法) 第三节:深度剖析各类数据结构(Array、List、Queue、Stack)及线程安全问题和yeild关键字 各种通讯连接方式 设计模式篇 第十二节: 总结Quartz.Net几种部署模式(IIS、Exe、服务部署【借

    ASP.NET MVC深入浅出系列(持续更新)   一. ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态模 ...

  3. centos linux系统日常管理3 服务管理ntsysv,chkconfig,系统日志rsyslog,last ,lastb ,exec,xargs,dmesg,screen,nohup,curl,ping ,telnet,traceroute ,dig ,nc,nmap,host,nethogs 第十六节课

    centos linux系统日常管理3  服务管理ntsysv,chkconfig,系统日志rsyslog,last ,lastb ,exec,xargs,dmesg,screen,nohup,cur ...

  4. 第十六节、基于ORB的特征检测和特征匹配

    之前我们已经介绍了SIFT算法,以及SURF算法,但是由于计算速度较慢的原因.人们提出了使用ORB来替代SIFT和SURF.与前两者相比,ORB有更快的速度.ORB在2011年才首次发布.在前面小节中 ...

  5. centos shell脚本编程2 if 判断 case判断 shell脚本中的循环 for while shell中的函数 break continue test 命令 第三十六节课

    centos  shell脚本编程2 if 判断  case判断   shell脚本中的循环  for   while   shell中的函数  break  continue  test 命令   ...

  6. 大白话5分钟带你走进人工智能-第二十六节决策树系列之Cart回归树及其参数(5)

                                                    第二十六节决策树系列之Cart回归树及其参数(5) 上一节我们讲了不同的决策树对应的计算纯度的计算方法, ...

  7. 第一百二十六节,JavaScript,XPath操作xml节点

    第一百二十六节,JavaScript,XPath操作xml节点 学习要点: 1.IE中的XPath 2.W3C中的XPath 3.XPath跨浏览器兼容 XPath是一种节点查找手段,对比之前使用标准 ...

  8. 第三百八十六节,Django+Xadmin打造上线标准的在线教育平台—HTML母版继承

    第三百八十六节,Django+Xadmin打造上线标准的在线教育平台—HTML母版继承 母板-子板-母板继承 母板继承就是访问的页面继承一个母板,将访问页面的内容引入到母板里指定的地方,组合成一个新页 ...

  9. 第三百七十六节,Django+Xadmin打造上线标准的在线教育平台—创建用户操作app,在models.py文件生成5张表,用户咨询表、课程评论表、用户收藏表、用户消息表、用户学习表

    第三百七十六节,Django+Xadmin打造上线标准的在线教育平台—创建用户操作app,在models.py文件生成5张表,用户咨询表.课程评论表.用户收藏表.用户消息表.用户学习表 创建名称为ap ...

随机推荐

  1. docker互联机制实现便捷互访

    何为容器互联 & 为何需要容器互联 容器的互联是一种让多个容器中应用进行快速交互的方式,它会在源和接收容器之间创建连接关系,接收容器可以通过容器名快速访问到源容器,而不用指定具体的 ip 地址 ...

  2. if (flag)

    var flag = false;//暂停标记if (flag){ alert("aa")}else { alert("bb")}bb if (flag) = ...

  3. Dart语言学习(七)Dart Map类型

    映射(Maps)是无序的键值对: 常用属性: keys 获取所有的key值 values 获取所有的value值 isEmpty 是否为空 isNotEmpty 是否不为空 常用方法: remove( ...

  4. tomcat服务器启动执行的两个方法

    第一 SetApplicationContext(需要继承ApplicationContextAware)重写 第二 ContextInitialize(需要继承servleContet)重写,(co ...

  5. acm数论之旅--唯一分解定理

    题目: 给出n,问n = b^p中p符合该等式的最大值 分析: 先求出所有n的质因子,然后对这m个质因子分类统计,比如 n = 36时,可以分成 2个2,2个3,然后求出所有这些基数的 最大公因数gc ...

  6. python 的集合

    set  的特点: 把不同的元素组合在一起,元素值必须是可哈希不可变的 set 的创建 s = set ('alex li') print(s) 表现形式:去重 {'e', 'i', ' ', 'l' ...

  7. ztree-可拖拽可编辑的树

    <!DOCTYPE html> <HTML> <HEAD> <TITLE> ZTREE DEMO - addNodes / editName / rem ...

  8. drat笔记

    安装dart https://www.dartcn.com/install http://www.cndartlang.com/920.html 所有执行的方法都在main里面. main() {} ...

  9. 五、request模块

    描述:requests是python的一个第三方HTTP(Hypertext Transfer Protocol,超文本传输协议)库,它比python自带的网络库urllib更加简单.方便和人性化:使 ...

  10. 13,viewport

    set viewport:~是一种函数,功能是为图形输出设置当前视口. 怎样处理移动端1px被渲染成2px的问题(略)