第十六节:Linq用法大全(四)
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用法大全(四)的更多相关文章
- 第四百一十六节,Tensorflow简介与安装
第四百一十六节,Tensorflow简介与安装 TensorFlow是什么 Tensorflow是一个Google开发的第二代机器学习系统,克服了第一代系统DistBelief仅能开发神经网络算法.难 ...
- 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的无状态模 ...
- 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 ...
- 第十六节、基于ORB的特征检测和特征匹配
之前我们已经介绍了SIFT算法,以及SURF算法,但是由于计算速度较慢的原因.人们提出了使用ORB来替代SIFT和SURF.与前两者相比,ORB有更快的速度.ORB在2011年才首次发布.在前面小节中 ...
- centos shell脚本编程2 if 判断 case判断 shell脚本中的循环 for while shell中的函数 break continue test 命令 第三十六节课
centos shell脚本编程2 if 判断 case判断 shell脚本中的循环 for while shell中的函数 break continue test 命令 ...
- 大白话5分钟带你走进人工智能-第二十六节决策树系列之Cart回归树及其参数(5)
第二十六节决策树系列之Cart回归树及其参数(5) 上一节我们讲了不同的决策树对应的计算纯度的计算方法, ...
- 第一百二十六节,JavaScript,XPath操作xml节点
第一百二十六节,JavaScript,XPath操作xml节点 学习要点: 1.IE中的XPath 2.W3C中的XPath 3.XPath跨浏览器兼容 XPath是一种节点查找手段,对比之前使用标准 ...
- 第三百八十六节,Django+Xadmin打造上线标准的在线教育平台—HTML母版继承
第三百八十六节,Django+Xadmin打造上线标准的在线教育平台—HTML母版继承 母板-子板-母板继承 母板继承就是访问的页面继承一个母板,将访问页面的内容引入到母板里指定的地方,组合成一个新页 ...
- 第三百七十六节,Django+Xadmin打造上线标准的在线教育平台—创建用户操作app,在models.py文件生成5张表,用户咨询表、课程评论表、用户收藏表、用户消息表、用户学习表
第三百七十六节,Django+Xadmin打造上线标准的在线教育平台—创建用户操作app,在models.py文件生成5张表,用户咨询表.课程评论表.用户收藏表.用户消息表.用户学习表 创建名称为ap ...
随机推荐
- 解决async 运行多线程时报错RuntimeError: There is no current event loop in thread 'Thread-2'
原来使用: loop = asyncio.get_event_loop()task = asyncio.ensure_future(do_work(checker))loop.run_until_co ...
- 运行时错误'430': 类不支持自动化或不支持期望的接口。New ADODB.Connection问题
运行时错误'430': 类不支持自动化或不支持期望的接口. 问题: 经调试发现,是运行到下面语句时出错:Set MyConn = New ADODB.Connection 运行到这里是提示本错误 这 ...
- Kubernetes 升级记录:从 1.16.3 升级至 1.17.0
参考官方文档 Upgrading kubeadm clusters 在 ubuntu 18.04 上完成了升级,记录一下升级步骤. 一.升级第一个 master 节点 apt-get 安装 kubea ...
- bbs系统的相关知识点
1.注册功能 1.注册功能往往都会由很多校验性的需求 所以这里我们用到了forms组件 项目中可能有多个地方需要用到不同的forms组件 为了解耦合 但是创建一个py文件 专门用来存放项目用到的所有的 ...
- 使用SQL命令行更改数据库字段类型
ALTER TABLE 表名 MODIFY COLUMN 字段名 数据类型 添加列 ALTER TABLE students ADD COLUMN address VARCHAR(100) DEFAU ...
- Codeforces Round #610 (Div. 2)E(模拟,DFS)
先找到一条多边形的边,然后循环一圈输出多边形上的点.把每个三角形看作一个结点,以两个三角形之间公用边为边建立一张图,DFS输出叶子结点,则得到先切后切的顺序. #define HAVE_STRUCT_ ...
- python在线测试代码及教程
python/Java在线测试代码:http://www.pythontutor.com/visualize.html#mode=edit廖雪峰Python教学:https://www.liaoxue ...
- 字符串类型:char,varchar,text,enum,set
字符串类型 1.char 格式:char (M) 2.varchar 格式:varchar (M) [注意]M表示允许的字符串长度[65535].M表示的是字符数,而不是字节数.但是最大长度的使用是按 ...
- vscode生成文件头注释(python)
文件→首选项→用户代码片段→选python 在大括号内添加如下内容: "Print infomation": { "prefix": "prelog& ...
- 2017年陕西省网络空间安全技术大赛——人民的名义-抓捕赵德汉2——Writeup
下载下来的文件是一个jar包,用die和binwalk检查,确实是一个纯正的jar包 java -jar FileName运行jar包,观察文件的外部特征,发现也是判断password的题目 用查 ...