《C#本质论》读书笔记(14)支持标准查询操作符的集合接口
14.2.集合初始化器
- static void Main(string[] args)
- {
- List<string> sevenWorldBlunders;
- sevenWorldBlunders = new List<string>()
- {
- "Wealth without work",
- "Pleasure without conscience",
- "Knowledge without character",
- "Commerce without morality",
- "Science without humanity",
- "Worship without sacrifice",
- "Politics without principle"
- };
- Print(sevenWorldBlunders);
- Console.Read();
- }
- private static void Print<T>(IEnumerable<T> items)
- {
- foreach (T item in items)
- {
- Console.WriteLine(item);
- }
- }
状态共享
- Stack<int> stack = new Stack<int>();
- Stack<int>.Enumerator stackEnumerator = stack.GetEnumerator();
- int number;
- while (stackEnumerator.MoveNext())
- {
- number = stackEnumerator.Current;
- Console.WriteLine(number);
- }
2
清理状态
- System.Collections.Generic.Stack<int> stack = new System.Collections.Generic.Stack<int>();
- Stack<int>.Enumerator stackEnumerator = stack.GetEnumerator();
- IDisposable disposable;
- try
- {
- int number;
- while (stackEnumerator.MoveNext())
- {
- number = stackEnumerator.Current;
- Console.WriteLine(number);
- }
- }
- finally
- {
- //显式类型转换用于IEnumerator < T >
- disposable = (IDisposable)stackEnumerator;
- disposable.Dispose();
- //IEnumerator将使用操作符,除非IDisposable支持在编译时是已知的
- disposable = (stackEnumerator as IDisposable);
- if (disposable != null)
- {
- disposable.Dispose();
- }
- }
- System.Collections.Generic.Stack<int> stack = new System.Collections.Generic.Stack<int>();
- int number;
- using (Stack<int>.Enumerator stackEnumerator = stack.GetEnumerator())
- {
- while (stackEnumerator.MoveNext())
- {
- number = stackEnumerator.Current;
- Console.WriteLine(number);
- }
- }
14.4.标准查询操作符
- public class Patent
- {
- public string Title { get; set; }
- public string YearOfPublication { get; set; }
- public string ApplicationNumber { get; set; }
- public long[] InventorIds { get; set; }
- public override string ToString()
- {
- return string.Format("{0}({1})", Title, YearOfPublication);
- }
- }
- public class Inventor
- {
- public long Id{ get; set; }
- public string Name { get; set; }
- public string City { get; set; }
- public string State { get; set; }
- public string Country { get; set; }
- public override string ToString()
- {
- return string.Format("{0},({1},{2})", Name, City, State);
- }
- }
- public static class PatentData
- {
- public static readonly Inventor[] Inventors = new Inventor[]
- {
- new Inventor()
- {
- Name = "胡韩三",City ="韩国",State="SE",Country="KOR", Id =1,
- },
- new Inventor()
- {
- Name = "Michael Jackson",City ="美国",State="indiana",Country="USA", Id =2,
- },
- new Inventor()
- {
- Name = "唐三三",City ="中国",State="CQ",Country="CHN", Id =3,
- },
- new Inventor()
- {
- Name = "John Michaelis",City ="芝加哥",State="IL",Country="USA", Id =4,
- },
- new Inventor()
- {
- Name = "Mary Phelps Jacob",City ="纽约",State="NY",Country="KOR", Id =5,
- }
- };
- public static readonly Patent[] Patents = new Patent[]
- {
- new Patent()
- {
- Title="留声机",YearOfPublication="1877",InventorIds = new long[]{1}
- },
- new Patent()
- {
- Title="活动电影放映机",YearOfPublication="1888",InventorIds = new long[]{1}
- },
- new Patent()
- {
- Title="电报机",YearOfPublication="1837",InventorIds = new long[]{4}
- },
- new Patent()
- {
- Title="飞机",YearOfPublication="1903",InventorIds = new long[]{2,3}
- },
- new Patent()
- {
- Title="蒸汽机车",YearOfPublication="1815",InventorIds = new long[]{5}
- },
- new Patent()
- {
- Title="露背胸罩",YearOfPublication="1914",InventorIds = new long[]{7}
- },
- };
- }
- class Program
- {
- static void Main(string[] args)
- {
- IEnumerable <Patent> patents = PatentData.Patents;
- Print(patents);
- Console.WriteLine();
- IEnumerable<Inventor> inventors = PatentData.Inventors;
- Print(inventors);
- Console.ReadKey();
- }
- private static void Print<T>(IEnumerable<T> items)
- {
- foreach (T item in items)
- {
- Console.WriteLine(item);
- }
- }
- }
14.4.1
Where()筛选
- IEnumerable <Patent> patents = PatentData.Patents;
- //where
- patents = patents.Where(p => p.YearOfPublication.StartsWith("18"));
- Print(patents);
14.4.2
Select()投射
- IEnumerable <Patent> patents = PatentData.Patents;
- IEnumerable<Patent> patentsOf1800 =
- patents.Where(p => p.YearOfPublication.StartsWith("18"));
- IEnumerable<string> items =
- patentsOf1800.Select(p => p.ToString());
- Print(items);
- string rootDirectory = @"E:\MI-O2O商城APP\psSystem";
- string serchPattern = "*.html";
- IEnumerable<string> fileList = Directory.GetFiles(rootDirectory, serchPattern);
- IEnumerable<FileInfo> files = fileList.Select(file => new FileInfo(file));
- Print(files);
System.IO.FileInfo 对象。
- string rootDirectory = @"E:\MI-O2O商城APP\psSystem";
- string serchPattern = "*.html";
- IEnumerable<string> fileList = Directory.GetFiles(rootDirectory, serchPattern);
- var items = fileList.Select(
- file =>
- {
- FileInfo fileinfo = new FileInfo(file);
- return new
- {
- FileName = fileinfo.Name,
- Size = fileinfo.Length
- };
- });
14.4.3
Count()计数
- IEnumerable<Patent> patents = PatentData.Patents ;
- Console.WriteLine("Patent Count:{0}",patents.Count());
- Console.WriteLine("Patent Count in 1800s:{0}",
- patents.Count(p=>p.YearOfPublication.StartsWith("18")));
if(patents.Count()>0){...}),那首选的做法应使用Any()操作符(if(patents.Any()){...})只尝试遍历集合中的一项,成功返回true而不会遍历整个序列。
14.4.4
推迟执行
- IEnumerable<Patent> patents = PatentData.Patents;
- bool result;
- patents = patents.Where(
- p =>
- {
- if (result = p.YearOfPublication.StartsWith("18"))
- {
- Console.WriteLine("\t" + p);
- }
- return result;
- });
- Console.WriteLine("1,在1900年代之前的专利:");
- //1.foreach会循环分解成一个MoveNext()调用,//触发每项Lambda表达式
- foreach (var patent in patents)
- {
- }
- Console.WriteLine();
- Console.WriteLine("2.第二个清单在1900年代之前的专利:");
- //2.Enumerable的Count()函数会再次触发每一项的Lambda表达式
- Console.WriteLine(" 这里有 {0} 个专利在1900年之前..",patents.Count());
- Console.WriteLine();
- Console.WriteLine("3.第三个清单在1900年代之前的专利:");
- //3.ToArray()(或ToList()、ToDictinary()或ToLiikup())会没想再次触发Lambda
- patents = patents.ToArray();
- Console.Write(" 这里有 ");
- Console.WriteLine("{0} 个专利在1900年之前..", patents.Count());
14.4.5
OrderBy()和ThenBy()
- OrderBy()返回的是是一个IOrderEnumerable<T>接口,而不是IEnumerable<T>。
- IOrderEnumerable<T>派生自 IEnumerable<T>。
- OrderBy().OrderBy() 重复调用就会撤销上一个OrderBy()的工作。
- 指定额外的排序条件,使用ThenBy()(ThenBy扩展自IOrderEnumerable<T>而不是IEnumerable<T>)。
14.4.6
Join()内部连接
- public class Department
- {
- public long Id { get; set; }
- public string Name { get; set; }
- public override string ToString()
- {
- return string.Format("{0}", Name);
- }
- }
- public class Employee
- {
- public int Id { get; set; }
- public string Name { get; set; }
- public string Title { get; set; }
- public int DepartmentId { get; set; }
- public override string ToString()
- {
- return string.Format("{0}({1})", Name, Title);
- }
- }
- public static class CorporateData
- {
- public static readonly Department[] Departments = new Department[]
- {
- new Department() {Name = "Corporate", Id = 0},
- new Department() {Name = "Finance", Id = 1},
- new Department() {Name = "Engineering", Id = 2},
- new Department() {Name = "Information Technology", Id = 3},
- new Department() {Name = "Research", Id = 4},
- new Department() {Name = "Marketing", Id = 5},
- };
- public static readonly Employee[] Employee = new Employee[]
- {
- new Employee() {Name = "Mark Michaelis", Title = "Chief Computer Nerd", DepartmentId = 0},
- new Employee() {Name = "Michael Stokesbary", Title = "Senior Computer Wizard", DepartmentId = 2},
- new Employee() {Name = "Brian Jones", Title = "Enterprise Integration Guru", DepartmentId = 2},
- new Employee() {Name = "Jewel Floch", Title = "Bookkeeper Extraordinaire", DepartmentId = 1},
- new Employee() {Name = "Robert Stocksbary", Title = "Expert Mainframe Engineer", DepartmentId = 3},
- new Employee() {Name = "paul R.Bramsman", Title = "Programmer Extraodinaire", DepartmentId = 2},
- new Employee() {Name = "Thomas Heavey", Title = "Software Architect", DepartmentId = 2},
- new Employee() {Name = "John Michaelis", Title = "Inventor", DepartmentId = 4},
- };
- }
- static void Main(string[] args)
- {
- Department[] departments = CorporateData.Departments;
- Employee[] employees = CorporateData.Employee;
- //写代码......
- Console.ReadKey();
- }
- private static void Print<T>(IEnumerable<T> items)
- {
- foreach (T item in items)
- {
- Console.WriteLine(item);
- }
- }
- public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer,
- IEnumerable<TInner> inner, //指定连接的集合
- Func<TOuter, TKey> outerKeySelector, //指出外接键
- Func<TInner, TKey> innerKeySelector, //指定集合的键
- Func<TOuter, TInner, TResult> resultSelector); //输出结果
- var items = employees.Join(
- departments,//Enumerable<TInner> inner :指定连接的集合
- employee => employee.DepartmentId,//Func<TOuter, TKey> outerKeySelector:指出外接键
- department => department.Id,// Func<TInner, TKey> innerKeySelector:指定集合的键
- (employee, department) => new // Func<TOuter, TInner, TResult> resultSelector:输出结果
- {
- employee.Id,
- employee.Name,
- employee.Title,
- department = department
- }
- );
- Print(items);
14.4.7
GroupBy()分组
- Employee[] employees = CorporateData.Employee;
- IEnumerable<IGrouping<int, Employee>> groupedEmployees =
- employees.GroupBy(e => e.DepartmentId);
- foreach (IGrouping<int, Employee> employeeGroup in groupedEmployees)
- {
- Console.WriteLine();
- foreach (Employee employee in employeeGroup)
- {
- Console.WriteLine("\t" + employee);
- }
- Console.WriteLine("\tCount:" + employeeGroup.Count());
14.4.8
GroupJoin()一对多关系
如果创建员工列表,Join()提供的代码就可提供正确的结果。但是想要表示部门,理想的是显示一个部门的所有员工集合,而不是部门——员工关系都创建一条匿名类型的记录。
- public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer,
- IEnumerable<TInner> inner, //指定连接的集合
- Func<TOuter, TKey> outerKeySelector, //指出外接键
- Func<TInner, TKey> innerKeySelector, //指定集合的键
- Func<TOuter, IEnumerable<TInner>, TResult> resultSelector); //输出结果
- Department[] departments = CorporateData.Departments;
- Employee[] employees = CorporateData.Employee;
- var items = departments.GroupJoin(
- employees,
- department => department.Id,
- employee => employee.DepartmentId,
- (department, departmentEmployees) => new
- {
- department.Id,
- department.Name,
- Employees = departmentEmployees
- });
- foreach (var item in items)
- {
- Console.WriteLine("{0}", item.Name);
- foreach (Employee employee in item.Employees)
- {
- Console.WriteLine("\t"+employee);
- }
- }
SQL中没有与GroupJoin()等价的东西,这是由于SQL返回的数据基于记录,而不分层次结构。
14.4.9
SelectMany()
- var worldCup2014Finalists = new[]
- {
- new
- {
- TeamName="France",
- Players =new string[]
- {
- "本泽马","里贝里","格列兹曼","吉鲁","雷米",
- "卡巴耶","波巴","马图伊迪","瓦拉内","萨科",
- "德比希","曼加拉","穆萨-西索科","萨尼亚","埃弗拉",
- "洛里","鲁菲尔","朗德罗","马武巴","马图伊迪"
- }
- },
- new
- {
- TeamName="Italy",
- Players =new string[]
- {
- "布冯","德希利奥","基耶利尼","达米安","蒂亚戈-莫塔",
- "坎德雷瓦","阿巴特","马尔基西奥","巴洛特利","卡萨诺",
- "切尔奇","巴尔扎利","西里古","佩林","阿奎拉尼",
- "德罗西","伊莫比莱","帕罗洛","博努奇","帕莱塔"
- }
- }
- };
Print(players);
14.4.10
更多标准查询操作符
- static void Main(string[] args)
- {
- IEnumerable<object> stuff = new object[]
- {
- new object(),1,3,5,7,9,"\"thing\"",Guid.NewGuid()
- };
- Print("Stuff:{0}", stuff);
- IEnumerable<int> even = new int[] {0, 2, 4, 6, 8};
- Print("【even】:{0}", even);
- IEnumerable<int> odd = stuff.OfType<int>();//筛选指定类型<T>的元素
- Print("【odd】:{0}", odd);
- IEnumerable<int> numbers = even.Union(odd);//并集
- Print("【numbers】odd和even的并集:{0}", numbers);
- Print("numbers并集even(Union):{0}", numbers.Union(even));
- Print("numbers连接odd(Concat):{0}", numbers.Concat(odd));
- Print("numbers交集even(Intersection):{0}", numbers.Intersect(even));
- Print("去掉重复(Distinct):{0}", numbers.Concat(odd).Distinct());
- if (!numbers.SequenceEqual(numbers.Concat(odd).Distinct()))
- {
- throw new Exception("Unexpectedly unequal");
- }
- else
- {
- Console.WriteLine(@"Collection ""SequenceEquals"""+
- "collection.Concat(odd).Distinct())");
- Print("反转(Reverse):{0}", numbers.Reverse());
- Print("平均值(Average):{0}", numbers.Average());
- Print("和(Sum):{0}", numbers.Sum());
- Print("最大值(Max):{0}", numbers.Max());
- Print("最小值(Min):{0}", numbers.Min());
- }
- Console.ReadKey();
- }
- private static void Print<T>(string format,IEnumerable<T> items)
- {
- StringBuilder text = new StringBuilder();
- foreach (T item in items.Take(items.Count()-1))
- {
- text.Append(item + ",");
- }
- text.Append(items.Last());
- Console.WriteLine(format,text);
- }
- private static void Print<T>(string format, T item)
- {
- Console.WriteLine(format, item);
- }
《C#本质论》读书笔记(14)支持标准查询操作符的集合接口的更多相关文章
- 十四、C# 支持标准查询运算符的集合接口
支持标准查询运算符的集合接口. System.Linq.Enumeralbe类提供的一些常用的API 来执行集合处理 1.匿名类型 2.隐匿类型的局部变量 3.集合初始化器 4.集合 5.标准查询运算 ...
- Linq to BBJECT之非延时标准查询操作符
非延时标准查询操作符是指不具备延时查询特性的标准查询操作符,这些操作符一般用于辅助延时标准查询操作符使用. 1.ToArray操作符 ToArray操作符用于将一个输入序列转换成一个数组. 方法原型: ...
- LINQ标准查询操作符详解(转)
一. 关于LINQ LINQ 英文全称是“Language-Integrated Query”,中文为“语言集成查询”,它是微软首席架构师.Delphi 之父和C# 之父——Anders ...
- Linq to OBJECT延时标准查询操作符
1.Where 操作符用于限定输入集合中的元素,将符合条件的元素组织声称一个序列结果.2.Select 操作符用于根据输入序列中的元素创建相应的输出序列中的元素,输出序列中的元素类型可以与输入序列中 ...
- LINQ入门教程之各种标准查询操作符(二)
续上篇LINQ入门教程之各种标准查询操作符(一) LINQ入门教程之各种标准查询操作符(二) 7. 聚合操作符 8. 集合操作符 9. 生成操作符 #region 生成操作符 即从现有序列的值中 ...
- Linq to Object之非延迟标准查询操作符
非延时标准查询操作符是指不具备延时查询特性的标准查询操作符,这些操作符一般用于辅助延时标准查询操作符使用. 1.ToArray操作符 ToArray操作符用于将一个输入序列转换成一个数组. 方法原型: ...
- LINQ入门教程之各种标准查询操作符(一)
好久之前就想系统的学习下LINQ,好久之前…… 本篇文章主要介绍LINQ等的标准查询操作符,内容取自<LINQ高级编程>,后续还会介绍LINQ to XML ,LINQ to SQL. L ...
- Linq to Object 延迟标准查询操作符
1.Where 操作符用于限定输入集合中的元素,将符合条件的元素组织声称一个序列结果.2.Select 操作符用于根据输入序列中的元素创建相应的输出序列中的元素,输出序列中的元素类型可以与输入序列中 ...
- Linq 标准查询操作符三
本文介绍了LINQ标准查询操作符.没有这些操作符,LINQ就不会存在.本文为理解这些操作符的功能提供了很好的基础.了解它们将会很有帮助,因为LINQ的各种Provider都是基于这些操作符来完成各自丰 ...
随机推荐
- 剑指Offer 链表中倒数第k个结点
题目描述 输入一个链表,输出该链表中倒数第k个结点. 思路: 法1:设置2个指针p,q.p先移动k次,然后pq同时后移,p到链表尾尾的时候,q指向倒数第k个节点. 注意://需要考虑k=0,以 ...
- opencv统计二值图黑白像素个数
#include "iostream" #include "queue" #include "Windows.h" #include < ...
- 学习高博SLAM(1)
这几天按照高博的博客做了一起做RGB-D SLAM (1)和(2) ,,其中大部分步骤都没问题 开发环境是ubuntu14.04+indigo 有几个问题就是: (1)我的电脑不能加载PPA,原因是: ...
- SPOJ 375 Query on a tree
Description 给出一个树,每条边有边权,支持两种操作,询问 \(u,v\) 路径上边权最大值,修改第 \(i\) 条边的边权,\(n\leqslant 10^4,T\leqslant 10\ ...
- NDK学习4: Eclipse HelloWorld
NDK学习4: Eclipse HelloWorld 1.配置Eclipse NDK环境 Window->preferences->android->ndk 2.新建Andro ...
- yuv转bmp
#ifdef _INTERFACE_H #error _INTERFACE_H has be exsisted #else #define _INTERFACE_H #include "st ...
- php上传文件大小限制修改
打开php.ini 1.最大上传文件大小: upload_max_filesize=2M 改成自己需要的大小 2.最大post大小: post_max_size=2M 改成自己需要的大小,第二个一般比 ...
- phpcms新闻轮播图实现
首页如果有新闻的轮播图,点击图片可以进入相关的新闻.因为已经使用外部js轮播插件,所以想不修改插件进行轮播 我用的js插件是yx-rotaion插件,配合phpcms的get工具箱对新闻进行读取并抽取 ...
- SqlBulkCopy 批量复制数据到数据表
使用 SqlBulkCopy 类只能向 SQL Server 表写入数据.但是,数据源不限于 SQL Server:可以使用任何数据源,只要数据可加载到 DataTable 实例或可使用 IDataR ...
- PHP中文字符串编码转换
2016年2月26日 16:47:13 星期五 情景: PHP从csv导入数据时乱码 $name = mb_convert_encoding($name, 'UTF-8', 'ASCII,GBK,GB ...