IEnumerable的一些基本方法
在说明用法之后,先要弄点数据。
class Product
{
public int ID { get; set; }
public string Name { get; set; }
public string Region { get; set; }
public decimal Price { get; set; }
public bool IsFavorite { get; set; }
}
List<Product> products = new List<Product> {
new Product { ID=, Name="路易十八比萨饼", Region="意大利", Price=, IsFavorite = false },
new Product { ID=, Name="澳洲胡桃", Region="澳洲", Price=, IsFavorite = false },
new Product { ID=, Name="Almas鱼子酱", Region="伊朗", Price=, IsFavorite = false },
new Product { ID=, Name="和牛肉", Region="日本", Price=, IsFavorite = true },
new Product { ID=, Name="麝香猫咖啡豆", Region="印尼", Price=, IsFavorite = true },
new Product { ID=, Name="大红袍茶叶", Region="中国", Price=, IsFavorite = true },
new Product { ID=, Name="Kona Nigari矿泉水", Region="美国", Price=, IsFavorite = true },
new Product { ID=, Name="Diva伏特加", Region="北欧", Price=, IsFavorite = false },
new Product { ID=, Name="番红花的雄蕊", Region="地中海", Price=, IsFavorite = false },
};
一、ALL和ANY
bool allChina = products.All(p => p.Region == "中国");//所有项Region都要是中国,结果:False
bool anyChina = products.Any(p => p.Region == "中国");//某一项Region是中国,结果:True
二、聚集
int countIdGreater5 = products.Count(p => p.ID > );//ID大于5的记录数,结果:4
decimal maxPrice = products.Max(p => p.Price);//金额最高,结果:208000
int minId = products.Min(p => p.ID);//编号最小,结果:1
decimal avgPrice = products.Average(p => p.Price);//金额平均值,结果:53538
decimal sumPrice = products.Sum(p => p.Price);//金额总值 结果:481842
三、累加器
Product aggregate1 = products.Aggregate((total, next) =>//累加器,对products中每一个元素执行一次Func
{
total.Price += next.Price;
return total;
});
上面的代码可以做一下优化
decimal aggregate2 = products.Aggregate(2000M, (total, next) =>//累加器可以给初始值,这里给的值是2000
{
total += next.Price;
return total;//这里返回的类型和初始值一致
});
累加器操作的时候尽量用值类型,上面2段代码如果一起执行,aggregate2的值就会出现异常。
四、SELECT
string[] select1 = products.Select(p => p.Name).ToArray();//选择单列,可以转换成数组
var select2 = products.Select(p => new { p.ID, p.Name }).ToDictionary(d => d.ID);//选择两列,可以转换成键值对
var selectMore = products.Select(p => new { p.ID, p.Name, p.Price }).ToList();//选择多列,可以转换成对象
//键值对必须要保证键值是唯一的,在键值不唯一的情况可以使用ToLookup方法
var lookup = products.ToLookup(l => l.IsFavorite, p => new { p.ID, p.Name, p.Region, p.Price }).ToList();
lookup.ForEach(l =>
{
Console.WriteLine(l.Key ? "已收藏" : "未收藏");
l.ToList().ForEach(item => Console.WriteLine("\t{0}\t{1}\t{2}\t{3}", item.ID, item.Name, item.Region, item.Price));
});
五、ORDER BY
var rightOrder = products.OrderBy(p => p.IsFavorite).ThenByDescending(p => p.ID).ToList();//主IsFavorite,次ID
var errorOrder = products.OrderBy(p => p.IsFavorite).OrderByDescending(p => p.ID).ToList();//主ID,次IsFavorite
六、GROUP BY
var group = products.GroupBy(p => p.IsFavorite).Select(g => new { IsFavorite = g.Key, SumPrice = g.Sum(item => item.Price), CountItem = g.Count() }).ToList();
当然在写拉姆达表达式的时候,也顺便说一个LINQ的用法
var groupLinq = (from p in products
group p by p.IsFavorite
into g
select new { IsFavorite = g.Key, SumPrice = g.Sum(item => item.Price), CountItem = g.Count() }).ToList();
七、WHERE
List<Product> distinct = products.Distinct().ToList();//去掉重复的记录
List<Product> take = products.Take().ToList();//顺序取3条记录
List<Product> takeWhile = products.TakeWhile(p => p.ID <= ).ToList();//只要不满足条件了,返回所有当前记录
List<Product> skip = products.Skip().ToList();//顺序跳过3条记录
List<Product> skipWhile = products.SkipWhile(p => p.Price < ).ToList();//只要不满足条件了,返回所有剩余记录
List<Product> contains = products.Where(p => p.Name.Contains("红")).ToList();//包含“红”的集合
Product first = products.Where(p => p.Name.StartsWith("大")).First();//“大”开头的第一条记录 如果无记录,直接报异常
Product lastDefault = products.Where(p => p.Name.EndsWith("胡")).LastOrDefault();//“胡”结尾的最后一条记录 如果无记录,返回默认值(对象返回null)不会报异常
Product single = products.Where(p => p.ID == ).SingleOrDefault();//取单条记录,有多条时会报异常
Product elementDefault = products.ElementAtOrDefault();//返回第10条记录 如果没有第10条记录,返回默认值(对象返回null)不会报异常
八、默认
products.DefaultIfEmpty(new Product { ID = , Name = "默认产品", Region = "默认地区", Price = });//判断是否为空,是返回默认值,否返回products
单集合操作讲得差不多了,下面说一下多集合操作的,还是老套路,先弄点数据,这里我们数据用最普遍的DataTable格式
DataTable table1 = new DataTable();
table1.Columns.Add("ID");
table1.Columns.Add("Name");
table1.Columns.Add("Amount");
table1.Columns.Add("Description"); table1.Rows.Add("", "张三", "", "不知道和张三丰有什么关系?");
table1.Rows.Add("", "李四", "", "无");
table1.Rows.Add("", "王五", "", "是住你家隔壁的那位吗?"); DataTable table2 = new DataTable();
table2.Columns.Add("ID");
table2.Columns.Add("Name");
table2.Columns.Add("Amount");
table2.Columns.Add("Description");
table2.Rows.Add("", "张三", "", "不知道和张三丰有什么关系?");
table2.Rows.Add("", "老王", "", "这才是隔壁那位吧");
table2.Rows.Add("", "老刘", "", "无");
九、JOIN
//两表内联,结果有2条记录
var joinTable = table1.AsEnumerable().Join(table2.AsEnumerable(),
left => left["ID"].ToString(),
right => right["ID"].ToString(),
(left, right) => new {
LeftID = left["ID"].ToString(),
RightID = right["ID"].ToString(),
LeftName = left["Name"].ToString(),
RightName = right["Name"].ToString() }).ToList();
joinTable.ForEach(t => Console.WriteLine("{0}\t{1}\t{2}\t{3}", t.LeftID, t.RightID, t.LeftName, t.RightName));
十、GROUPJOIN
//以第一个表为基准,对第二个表进行分组
var groupJoinTable = table1.AsEnumerable().GroupJoin(table2.AsEnumerable(),
left => left["Description"].ToString(),
right => right["Description"].ToString(),
(key, g) => new {
Key = key["Description"].ToString(),
Count = g.Count(),
TotalAmount = g.Where(s => decimal.Parse(s["Amount"].ToString()) > ).Sum(s => decimal.Parse(s["Amount"].ToString()))
}).ToList();
groupJoinTable.ForEach(t => Console.WriteLine("{0}\t{1}\t{2}", t.Key, t.Count, t.TotalAmount));
这里的统计不会包括第一个表的记录,第一个表只何为一个索引使用
十一、比较两个表是否相等
bool isEqual = table1.AsEnumerable().Where(t => t["ID"].ToString() == "")
.SequenceEqual(table2.AsEnumerable().Where(t => t["ID"].ToString() == ""), DataRowComparer.Default);
Console.WriteLine(isEqual);
这里只是做了单条记录的比较,为的只是返回一个TRUE,整个集合比较也是可以的
十二、连接两个表,不去重复,列取公共部分
var concatTable = table1.AsEnumerable().Concat(table2.AsEnumerable()).ToList();
concatTable.ForEach(t => Console.WriteLine("{0}\t{1}\t{2}\t{3}", t["ID"], t["Name"], t["Amount"], t["Description"]));
十三、差集、交集、并集
//两表的差集
var exceptTable = table1.AsEnumerable().Except(table2.AsEnumerable(), DataRowComparer.Default).ToList();
exceptTable.ForEach(t => Console.WriteLine("{0}\t{1}\t{2}\t{3}", t["ID"], t["Name"], t["Amount"], t["Description"])); //两表的交集
var intersectTable = table1.AsEnumerable().Intersect(table2.AsEnumerable(), DataRowComparer.Default).ToList();
intersectTable.ForEach(t => Console.WriteLine("{0}\t{1}\t{2}\t{3}", t["ID"], t["Name"], t["Amount"], t["Description"])); //两表的并集
var unionTable = table1.AsEnumerable().Union(table2.AsEnumerable(), DataRowComparer.Default).ToList();
unionTable.ForEach(t => Console.WriteLine("{0}\t{1}\t{2}\t{3}", t["ID"], t["Name"], t["Amount"], t["Description"]));
最后说一个比较好玩的方法,还是老规矩,先弄数据
List<Store> stores = new List<Store>
{
new Store
{
ID = ,
Name = "城北",
Products = new List<Product> {
new Product { ID=, Name="路易十八比萨饼", Region="意大利", Price=, IsFavorite = false },
new Product { ID=, Name="澳洲胡桃", Region="澳洲", Price=, IsFavorite = false },
new Product { ID=, Name="Almas鱼子酱", Region="伊朗", Price=, IsFavorite = false }
}
},
new Store
{
ID = ,
Name = "城南",
Products = new List<Product> {
new Product { ID=, Name="和牛肉", Region="日本", Price=, IsFavorite = true },
new Product { ID=, Name="麝香猫咖啡豆", Region="印尼", Price=, IsFavorite = true },
new Product { ID=, Name="大红袍茶叶", Region="中国", Price=, IsFavorite = true }
}
},
new Store
{
ID = ,
Name = "城东",
Products = new List<Product> {
new Product { ID=, Name="Kona Nigari矿泉水", Region="美国", Price=, IsFavorite = true },
new Product { ID=, Name="Diva伏特加", Region="北欧", Price=, IsFavorite = false },
new Product { ID=, Name="番红花的雄蕊", Region="地中海", Price=, IsFavorite = false }
}
}
};
我把上面的9个产品分到了3个仓库里面存在,当我要查找金额小于10000的所有产品时,按以前的做法就要写2个FOREACH循环,现在用到SELECTMANY就方便多了
var selectMany = stores.SelectMany(s => s.Products).Where(p => p.Price < ).ToList();
selectMany.ForEach(item => Console.WriteLine("\t{0}\t{1}\t{2}\t{3}", item.ID, item.Name, item.Region, item.Price));
当然,也可以用LINQ的方式
var linqSelectMany = from s in stores
from p in s.Products
where p.Price <
select p;
linqSelectMany.ToList().ForEach(item => Console.WriteLine("\t{0}\t{1}\t{2}\t{3}", item.ID, item.Name, item.Region, item.Price));
IEnumerable的一些基本方法的更多相关文章
- C# 索引器,实现IEnumerable接口的GetEnumerator()方法
当自定义类需要实现索引时,可以在类中实现索引器. 用Table作为例子,Table由多个Row组成,Row由多个Cell组成, 我们需要实现自定义的table[0],row[0] 索引器定义格式为 [ ...
- 为IEnumerable扩展一个ForEach方法
IEnumerable没有一个ForEach方法,我们可以使用C#写一个扩展方法: Source Code: using System; using System.Collections.Generi ...
- IEnumerable接口的扩展方法
/// <summary>/// IEnumerable接口的扩展方法,支持它的实现类是List的情况/// </summary>using System.Collection ...
- C#对IQueryable<T>、IEnumerable<T>的扩展方法
#region IQueryable<T>的扩展方法 #region 根据第三方条件是否为真是否执行指定条件的查询 /// <summary> /// 根据第三方条件是否为真是 ...
- IEnumerable接口的Aggregate方法
以前小猪为了累加一个集合中的类容通常会写出类似这样的C#代码: string result ="": foreach (var item in items) { result+=i ...
- IEnumerable中的 Any方法
IEnumerable类中的 Any方法,表示集合中有任何一元素满足条件,返回就true , 该方法有两个重载 1. 不带任何参数,表示集合中有元素 2. 参入一个 Func<TSource, ...
- 为IEnumerable类型添加Add方法
IEnumerable类型原生是没有Add方法的,你可以用Contact方法去为它添加元素, 1 items = items.Concat(new[] { "foo" }); 也可 ...
- IEnumerable的一些基本方法 补充
接上一篇,我们发现两表连接方式默认为内连接,而我们在SQL中常用到的左连接没有封装方法.换句话说,微软放弃两表左连或右连的这种做法(只有在2个表都存在值时,这样的连接才有意义). 如果要实现表的左连接 ...
- IEnumerable对象的Distinct方法重写
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource ...
随机推荐
- 黑马day11 事务的四大特性
1.事务的四大特性:一个事务具有的最主要的特性.一个设计良好的数据库能够为我们保证这四大特性. 1.1原子性:原子性是指事务是一个不可切割的工作单位,事务中的操作要么都发生要么都不发生. 1.2一致性 ...
- 可以这样创建E-Notebook数据库
最新版的ChemDraw的名称是ChemOffice Professional 15.用户朋友们在使用它的E-Notebook功能的时候,会发现需要先创立一个数据库,作为上传文档的储存空间.并且还可以 ...
- CentOS7上elasticsearch5.0启动失败
CentOS7上elasticsearch5.0启动失败 刚一启动完直接就退出了 $ ./elasticsearch ... ERROR: bootstrap checks failed max fi ...
- 关于vue,angularjs1,react之间的对比
1.时间投入的问题:相对于react和angularjs,学习vue的时间成本低,而且容易上手. 2.JSX的可读性比较一般.代码的可读性不如vue,当然,vue也支持jsx,但是vue更提倡temp ...
- 巨蟒python全栈开发linux之centos1
1.linux服务器介绍 2.linux介绍 3.linux命令学习 linux默认有一个超级用户root,就是linux的皇帝 注意:我的用户名是s18,密码是centos 我们输入密码,点击解锁( ...
- PLSQL 用的让自己更舒心点!
每天开发时候 ,有时候会疲劳! 改下你的PLSQL 字体吧!
- py 与 pyc 文件
本文要说明的问题 pyc 文件是什么 pyc 文件的作用 py 与 pyc 文件冲突 pyc 文件是什么 当 py 文件加载后,py 文件被二进制编码成 pyc 文件.py 文件的修改时间被记录到 p ...
- 通过spring boot提供restful api
1 将返回设置为produces = "application/json" 返回给客户端json格式的response. 2 对各种异常的处理 各种异常如何返回给客户端? 各种异常 ...
- 查看虚拟机里的Centos7的IP(四)
这里之所以是查看下IP ,是我们后面要建一个Centos远程工具Xshell 连接Centos的时候,需要IP地址,所以我们这里先 学会查看虚拟机里的Centos7的IP地址 首先我们登录操作系统 用 ...
- Oracle 12c 读书笔记(二):Oracle数据库体系结构
以11g来分析 数据库实例包括:SGA和一系列后台管理.监控简称 数据库包括三种文件:数据文件.控制文件.重做日志文件 数据库实例和数据库是Orale数据库体系的核心部分 Oracle服务器和实例 实 ...