LINQ to Objects---立即执行的Enumerable类方法
本篇接上一篇:延时执行的Enumerable类方法,总结常用的立即执行的Enumerable类方法和它们的常用用法。
为了便于理解和记忆,DebugLZQ进行了分组。
1.ToArray序列转换成数组
2.ToList序列转换成List<T>
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace 立即执行的Enumerable类方法成员 { class Program { static void Main(string[] args) { //1.ToArray序列转换成数组 List<string> names =new List<string> { "DebugLZQ","Sarah","Jerry","Jeffrey","M&M"}; string[] takenames = names.ToArray(); string[] takenames2 = (from name in names where name.IndexOf("Je")>-1 select name).ToArray(); //2.ToList序列转换成List<T> string[] namesA = { "DebugLZQ", "Sarah", "Jerry", "Jeffrey", "M&M" }; List<string> takenames_ToList = namesA.ToList(); List<string> takenames_ToList2 = (from name in namesA select name).ToList(); // } } }
程序结果显而易见,所以没有写输出语句;
3.ToDictionary把序列转换为泛型Dictionary<TKey,TValue>
4.ToLookup用于将序列转换为泛型Lookup<TKey,TValue>
Dictionary和Lookup是非常近似的一对类型,都通过“键”访问相关的元素,不同的是Dictionary的Key和Value是一一对应关系,Lookup的Key和Value是一对多关系,Lookup没有公共构造函数,时能用ToLookup构建,创建后也不能删除Lookup中的元素。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ToDictionary { /// <summary> /// 3.ToDictionary把序列转换为泛型Dictionary<TKey,TValue> /// </summary> class Program { static void Main(string[] args) { List<GuestInfo> gList = new List<GuestInfo>() { new GuestInfo(){Name="Jeffrey", Age=33,Tel="136********"}, new GuestInfo(){ Name="DebugLZQ", Age=25,Tel="187********"}, new GuestInfo(){Name="Sarah", Age=24,Tel="159********"}, new GuestInfo(){Name="Jerry", Age=33,Tel="135********"}, new GuestInfo(){Name="Smith", Age=33,Tel="139********"} }; //ToDictionary把序列转换为泛型Dictionary //ToDictionary重载了4个方法 //a.用Name作为Dictionary的“键”,guest为“value” Dictionary<string, GuestInfo> dictionary1 = gList.ToDictionary(guest => guest.Name); foreach (var s in dictionary1 ) { Console.WriteLine("键值{0}:{1} {2} {3}",s.Key,s.Value.Name,s.Value.Age,s.Value.Tel ); } Console.WriteLine("--------------------------------"); Console.ReadKey(); //b.自定义比较器 Dictionary<string,GuestInfo> dictionary2=gList.ToDictionary(guest=>guest.Name,new MyEqualityComparer<string>()); foreach (var s in dictionary2) { Console.WriteLine("键值{0}:{1} {2} {3}", s.Key, s.Value.Name, s.Value.Age, s.Value.Tel); } Console.WriteLine("--------------------------------"); Console.ReadKey(); //c.用Name作为Dictionary的“键”,Tel属性为"value" Dictionary<string, string> dictionary3 = gList.ToDictionary(guest=>guest.Name,g=>g.Tel); foreach (var s in dictionary3) { Console.WriteLine("键值{0}:{1}", s.Key, s.Value); } Console.WriteLine("--------------------------------"); Console.ReadKey(); //d.自定义比较器 Dictionary<string, string> dictionary4 = gList.ToDictionary(guest=>guest.Name,g=>g.Tel,new MyEqualityComparer<string>()); foreach (var s in dictionary4) { Console.WriteLine("键值{0}:{1}", s.Key, s.Value); } Console.WriteLine("------------------------------------------------------"); Console.ReadKey(); /////////////// ///4.ToLookup用于将序列转换为泛型Lookup<TKey,TValue>。 ///Dictionary和Lookup是非常近似的一对类型,都通过“键”访问相关的元素,不同的是Dictionary的Key和Value是一一对应关系 ///Lookup的Key和Value是一对多关系 ///Lookup没有公共构造函数,时能用ToLookup构建,创建后也不能删除Lookup中的元素。 ///该方法也有4个原型,和上面的ToDictionary极像 /// //a. Name的第一个字符(字符串)作key ILookup<string, GuestInfo> lookup1 = gList.ToLookup(guest => guest.Name.Substring(0, 1)); foreach (var k in lookup1) { Console.WriteLine(k.Key);//键值 foreach (var v in k) { Console.Write("{0},{1},{2}",v.Name,v.Age,v.Tel ); } Console.WriteLine(); } Console.WriteLine("--------------------------------"); Console.ReadKey(); //b自定义比较器 ILookup<string, GuestInfo> lookup2 = gList.ToLookup(guest => guest.Name.Substring(0, 1), new MyEqualityComparer<string>()); foreach (var k in lookup2) { Console.WriteLine(k.Key);//键值 foreach (var v in k) { Console.Write("{0},{1},{2}", v.Name, v.Age, v.Tel); } Console.WriteLine(); } Console.WriteLine("--------------------------------"); Console.ReadKey(); //c ILookup<string, string> lookup3 = gList.ToLookup(guest=>guest.Name.Substring(0,1),g=>g.Name ); foreach (var k in lookup3) { Console.WriteLine(k.Key);//键值 foreach (var v in k) { Console.Write("{0} ", v); } Console.WriteLine(); } Console.WriteLine("--------------------------------"); Console.ReadKey(); //d自定义比较器 ILookup<string, string> lookup4 = gList.ToLookup(guest=>guest.Name.Substring(0,1),g=>g.Name,new MyEqualityComparer<string>()); foreach (var k in lookup4) { Console.WriteLine(k.Key);//键值 foreach (var v in k) { Console.Write("{0} ", v); } Console.WriteLine(); } Console.WriteLine("--------------------------------"); Console.ReadKey(); } } }
程序运行结果如下:
没有显示完全,后面一组输出和上面最后一组相同(只是使用了自定义的比较器)。
5.SequenceEqual 比较两个序列是否相等
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SequenceEqual { /// <summary> /// /// </summary> class Program { static void Main(string[] args) { //5.SequenceEqual 比较两个序列是否相等 //a比较两个序列 string[] names1 ={ "DebugLZQ","Sarah","Jerry","Jeffrey","M&M"}; List<string> names2 = new List<string> { "DebugLZQ", "Sarah", "Jerry", "Jeffrey", "M&M" }; bool equalornot = names1.SequenceEqual(names2); bool equalornot2 = names1.Skip(3).Take(2).SequenceEqual(names2.Take(3).SkipWhile(n=>n.Length==3)); Console.WriteLine("{0},{1}",equalornot,equalornot2 ); Console.WriteLine("----------------------------"); Console.ReadKey(); //b自定义比较器 bool equalornot3 = names1.SequenceEqual(names2, new MyEqualityComparer<string>(names2.ToArray())); Console.WriteLine("{0}",equalornot3); Console.ReadKey(); } } }
自定义的比较器如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SequenceEqual { //DebugLZQ提示: //如不知道具体的接口实现 //可以用vs提供的自动实现接口功能实现这个接口 class MyEqualityComparer<T> : IEqualityComparer<T> { private string[] sec; public MyEqualityComparer(string[] s) { sec = s; } #region IEqualityComparer<T> 成员 public bool Equals(T x, T y) { string temp = x as string; if (x != null) { return sec.Contains(temp); } return false; } public int GetHashCode(T obj) { return obj.GetHashCode(); } #endregion } }
可以使用VS自动实现接口的智能提示,完成接口的实现。
接口的实现方式有“实现接口”和“显式实现接口”之分,上面这种实现方式即“显示接口”方式,“显示实现接口”最显著的特征是实现的接口方法加了个完全限定名,这样显式实现之后,无法通过具体的类名来访问接口方法,只能通过接口名来访问,这样可以隐藏类的复杂性。
程序运行结果如下:
6.First 返回序列第一个满足条件元素
7.FirstOrDefault 返回序列第一个满足条件元素,如果没有找到则返回默认值
8.Last
9.LastOrDefault
10.Single返回序列中唯一的元素,如果序列中包含多个元素,会引发运行错误!
11.SingleOrDefault 找出序列中满足一定条件的元素,如果序列为空则返回默认值, 如果序列中包含多个多个元素会引发运行错误!!
12.ElementAt 获得指定索引处的元素
13.ElementAtOrDefault 获得指定索引处的元素,如果超出索引,则返回元素类型的默认值
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace First_FirstOrDefault_Last_LastOrDefault_ElementAt_ElementAtOrDefaul { class Program { static void Main(string[] args) { //6.First string[] names = { "DebugLZQ", "Sarah", "Jerry", "Jeffrey", "M&M" }; var item = names.First(); var item2 = names.First(n => n == "Sarah"); Console.WriteLine("{0},{1}",item,item2 ); Console.ReadKey(); //7.FirstOrDefault var item3 = names.FirstOrDefault(); var item4 = names.FirstOrDefault(n => n == "Sarah"); Console.WriteLine("{0},{1}", item3, item4); Console.ReadKey(); //8.Last var item5 = names.Last(); var item6 = names.LastOrDefault(n => n == "Sarah"); Console.WriteLine("{0},{1}", item5, item6); Console.ReadKey(); //9LastOrDefault var item7 = names.LastOrDefault(); var item8 = names.LastOrDefault(n => n == "Sarah"); Console.WriteLine("{0},{1}", item7, item8); Console.ReadKey(); //10.Single返回序列中唯一的元素,如果序列中包含多个元素,会引发运行错误! try { var item9 = names.Single(); } catch(Exception ex) { Console.WriteLine(ex.Message); } // var item10 = names.Single(n => n == "Sarah"); Console.WriteLine("{0}",item10 ); Console.ReadKey(); //11.SingleOrDefault 找出序列中满足一定条件的元素,如果序列为空则返回默认值, 如果序列中包含多个多个元素会引发运行错误!! try { var item11 = Enumerable.Empty<string>().SingleOrDefault(); Console.WriteLine("{0}",item11);//不报错,如果序列为空就返回默认值 } catch (Exception ex) { Console.WriteLine(ex.Message ); } try { var item12 = names.SingleOrDefault(); Console.WriteLine("{0}", item12);//报错,序列包含多行错误 } catch (Exception ex) { Console.WriteLine(ex.Message); } var item13 = Enumerable.Empty<string>().DefaultIfEmpty("DebugLZQ").SingleOrDefault(); Console.WriteLine("{0}", item13); var item14 = names.SingleOrDefault(n => n == "xxx"); Console.WriteLine("{0}", item14); Console.ReadKey(); //12ElementAt 获得指定索引处的元素 var item15 = names.ElementAt(3); Console.WriteLine("{0}", item15); Console.ReadKey(); //13ElementAtOrDefault 获得指定索引处的元素,如果超出索引,则返回元素类型的默认值 var item16 = names.ElementAtOrDefault(3); var item17 = names.ElementAtOrDefault(100); Console.WriteLine("{0},{1}",item16,item17); Console.ReadKey(); } } }
程序运行结果如下:
14.All序列中的所有元素是否都满足条件
15.Any序列中的元素是否存在或满足条件
16.Contains确定元素是否在序列中
17.Count序列包含元素的数量
18.LongCount获取一个Int64类型的元素数量
19.Aggregate将序列元素进行累加
20.Sum序列之和
21.Average序列平均值
22.Min序列的最小值
23.Max序列的最大值
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace All_Any_Count_LongCount_Aggregate_SumAverage_Min_Max { class Program { static void Main(string[] args) { string[] names = { "DebugLZQ", "Sarah", "Jerry", "Jeffrey", "M&M" }; //14All序列中的所有元素是否都满足条件 bool b1 = names.All(s=>s.GetTypeCode()==TypeCode.String ); bool b2 = names.All(s=>s.IndexOf("S")>-1); Console.WriteLine("{0},{1}",b1,b2); Console.ReadKey(); Console.WriteLine("----------------------"); //15Any序列中的元素是否存在或满足条件 bool p1 = names.Any(); bool p2 = names.Any(s => s.IndexOf("S")>-1); Console.WriteLine("{0},{1}", p1, p2); Console.ReadKey(); Console.WriteLine("----------------------"); //16Contains确定元素是否在序列中 //a bool q1 = names.Contains("MM"); //b自定义比较函数 bool q2 = names.Contains("MM", new MyEqualityComparer<string>()); Console.WriteLine("{0},{1}", q1, q2); Console.ReadKey(); Console.WriteLine("----------------------"); //17Count序列包含元素的数量 int i1 = names.Count(); int i2 = names.Count(n => n.Length == 5); Console.WriteLine("{0},{1}", i1, i2); Console.ReadKey(); Console.WriteLine("----------------------"); //18LongCount获取一个Int64类型的元素数量 long j1 = names.LongCount(); long j2 = names.LongCount(n => n.Length == 5); Console.WriteLine("{0},{1}",j1, j2); Console.ReadKey(); Console.WriteLine("----------------------"); //19Aggregate将序列元素进行累加 int[] nums = { 10,20,30,40,50}; int a1 = nums.Aggregate((n1,n2)=>n1+n2);//150 int a2 = nums.Aggregate(50,(n1,n2)=>n1+n2);//200 Console.WriteLine("{0},{1}", a1, a2); string s1 = names.Aggregate((name1,name2)=>string.Format("{0}、{1}",name1,name2)); string s2= names.Aggregate("The result is ",(name1, name2) => string.Format("{0}、{1}", name1, name2)); Console.WriteLine("{0}", s1); Console.WriteLine("{0}", s2); Console.ReadKey(); Console.WriteLine("----------------------"); //20Sum序列之和 int sum = nums.Sum(); //21Average序列平均值 double avg = nums.Average(); //22Min序列的最小值 int min = nums.Min(); //23Max序列的最大值 int max=nums.Max(); Console.WriteLine("{0},{1},{2},{3}", sum, avg,min,max); Console.ReadKey(); } } }
程序运行结果如下: