diff --git a/LinqStudy.Test/LinqToObject/GroupTest.cs b/LinqStudy.Test/LinqToObject/GroupTest.cs new file mode 100644 index 0000000..c511165 --- /dev/null +++ b/LinqStudy.Test/LinqToObject/GroupTest.cs @@ -0,0 +1,168 @@ +using System.Collections; +using System.Collections.Generic; + +using System.Linq; + +using Xunit; + +using LinqStudy; + +namespace LinqStudy.Test.LinqToObject +{ + /// + /// 分组操作符 + /// + public class GroupTest + { + /// + /// GroupBy: 根据指定的键选择器函数对序列的元素进行分组;延迟执行。 + /// 注意:Key即分组依据,可以常用的值类型,也可以是引用类型(可以自定义比较器)) + /// + [Fact] + public void GroupBy_Default_Test() + { + List peoples=new List() + { + new Person(){Id=1, Name="Andy", Age=10}, + new Person(){Id=2, Name="Bab", Age=20}, + new Person(){Id=3, Name="Babs", Age=20}, + new Person(){Id=4, Name="Cara", Age=30}, + new Person(){Id=5, Name="Carlton", Age=30}, + new Person(){Id=6, Name="Cora", Age=30}, + new Person(){Id=7, Name="Dawn", Age=40}, + new Person(){Id=8, Name="Debby", Age=40}, + new Person(){Id=9, Name="Dotty", Age=40}, + new Person(){Id=10, Name="Dove", Age=40}, + }; + + var group = peoples.GroupBy(p=>p.Age); + var groupCount = group.Count(); + + Assert.Equal(4,groupCount); + } + + /// + /// 延迟执行 + /// + [Fact] + public void GroupBy_Delay_Test() + { + List peoples=new List() + { + new Person(){Id=1, Name="Andy", Age=10}, + new Person(){Id=2, Name="Bab", Age=20}, + new Person(){Id=3, Name="Babs", Age=20}, + new Person(){Id=4, Name="Cara", Age=30}, + new Person(){Id=5, Name="Carlton", Age=30}, + new Person(){Id=6, Name="Cora", Age=30}, + }; + + var group = peoples.GroupBy(p=>p.Age); + + //改变数据源 + List peoples2=new List() + { + new Person(){Id=7, Name="Dawn", Age=40}, + new Person(){Id=8, Name="Debby", Age=40}, + new Person(){Id=9, Name="Dotty", Age=40}, + new Person(){Id=10, Name="Dove", Age=40}, + }; + peoples.AddRange(peoples2); + + //受数据源变化的影响,说明是延迟执行。 + var groupCount = group.Count(); + + Assert.Equal(4,groupCount); + } + + /// + /// 重载:keySelector, comparer + /// key:是引用类型,使用自定义比较器 + /// + [Fact] + public void GroupBy_keySelector_comparer_Test() + { + List peoples=new List() + { + new Teacher(){Id=1, Name="河南周口人", Hometown=new Hometown(){Province="河南", City="周口"}}, + new Teacher(){Id=2, Name="俺河南周口哩", Hometown=new Hometown(){Province="河南",City="周口"}}, + new Teacher(){Id=3, Name="上海宝山人", Hometown=new Hometown(){Province="上海",City="宝山"}}, + new Teacher(){Id=4, Name="上海松江人", Hometown=new Hometown(){Province="上海",City="松江"}}, + + }; + + var group = peoples.GroupBy(p=>p.Hometown,new HometownEqualityComparer()); + + var groupFirstNames=group.First().Select(q=>q.Name).ToList(); + var expected=new List(){"河南周口人","俺河南周口哩"}; + + Assert.Equal(expected,groupFirstNames); + } + + /// + /// 重载:keySelector, elementSelector + /// key:是引用类型,使用自定义比较器 + /// + [Fact] + public void GroupBy_keySelector_elementSelector_Test() + { + List peoples=new List() + { + new Teacher(){Id=1, Name="河南周口人", Hometown=new Hometown(){Province="河南", City="周口"}}, + new Teacher(){Id=1, Name="俺河南周口哩", Hometown=new Hometown(){Province="河南",City="周口"}}, + new Teacher(){Id=2, Name="上海宝山人", Hometown=new Hometown(){Province="上海",City="宝山"}}, + new Teacher(){Id=3, Name="上海松江人", Hometown=new Hometown(){Province="上海",City="松江"}}, + + }; + + var group = peoples.GroupBy(p=>p.Id,t=>t.Name).ToList(); + + var groupFirstNames=group[2].FirstOrDefault(); + var expected="上海松江人"; + + Assert.Equal(expected,groupFirstNames); + } + /// + /// 重载:keySelector elementSelector comparer + /// + [Fact] + public void GroupBy_keySelector_elementSelector_comparer_Test() + { + List peoples=new List() + { + new Teacher(){Id=1, Name="河南周口人", Hometown=new Hometown(){Province="河南", City="周口"}}, + new Teacher(){Id=2, Name="俺河南周口哩", Hometown=new Hometown(){Province="河南",City="周口"}}, + new Teacher(){Id=3, Name="上海宝山人", Hometown=new Hometown(){Province="上海",City="宝山"}}, + new Teacher(){Id=4, Name="上海松江人", Hometown=new Hometown(){Province="上海",City="松江"}}, + + }; + + var group = peoples.GroupBy(p=>p.Hometown,t=>t.Name,new HometownEqualityComparer()).ToList(); + + var groupFirstNames=group[2].FirstOrDefault(); + var expected="上海松江人"; + + Assert.Equal(expected,groupFirstNames); + } + + [Fact] + public void GroupBy_keySelector_resultSelector_Test() + { + List peoples=new List() + { + new Teacher(){Id=1, Name="河南周口人", Hometown=new Hometown(){Province="河南", City="周口"}}, + new Teacher(){Id=1, Name="俺河南周口哩", Hometown=new Hometown(){Province="河南",City="周口"}}, + new Teacher(){Id=3, Name="上海宝山人", Hometown=new Hometown(){Province="上海",City="宝山"}}, + new Teacher(){Id=4, Name="上海松江人", Hometown=new Hometown(){Province="上海",City="松江"}}, + + }; + + var group = peoples.GroupBy(p=>p.Id, (key,teacher) => teacher.Select(t=>t.Name)).ToList(); + + var groupFirstNames=group[2].FirstOrDefault(); + var expected="上海松江人"; + + Assert.Equal(expected,groupFirstNames); + } + } +} \ No newline at end of file diff --git a/LinqStudy.Test/LinqToObject/标准查询操作符.md b/LinqStudy.Test/LinqToObject/标准查询操作符.md index f1bcd91..f52e3ce 100644 --- a/LinqStudy.Test/LinqToObject/标准查询操作符.md +++ b/LinqStudy.Test/LinqToObject/标准查询操作符.md @@ -31,11 +31,13 @@ ## 相等操作符 ## 量词操作符 + Any All ## 分区操作符 + Take 返回序列中,从0开始的连续指定项数据子序列;延迟执行。 - TakeWhile \ No newline at end of file + TakeWhile diff --git a/LinqStudy/Models/Hometown.cs b/LinqStudy/Models/Hometown.cs new file mode 100644 index 0000000..570a23c --- /dev/null +++ b/LinqStudy/Models/Hometown.cs @@ -0,0 +1,21 @@ +using System; + +namespace LinqStudy +{ + /// + /// 家乡类 + /// + public class Hometown + { + /// + /// 省份 + /// + /// + public string Province{get;set;} + + /// + /// 城市 + /// + public string City{get;set;} + } +} diff --git a/LinqStudy/Models/HometownCompare.cs b/LinqStudy/Models/HometownCompare.cs new file mode 100644 index 0000000..f81e968 --- /dev/null +++ b/LinqStudy/Models/HometownCompare.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace LinqStudy +{ + /// + /// 家乡 比较器 + /// + public class HometownCompare : IComparer + { + int IComparer.Compare(Hometown x, Hometown y) + { + int compareResult = 0; + + if (x == null && y == null) + { + compareResult = 0; + } + + else if (x == null) + { + compareResult = 1; + } + else if (y == null) + { + compareResult = -1; + } + else + { + if(x.Province == y.Province) + { + compareResult = string.Compare(x.City,y.City); + } + else + { + compareResult = string.Compare(x.Province,y.Province); + } + } + + return compareResult; + } + } +} diff --git a/LinqStudy/Models/HometownEqualityComparer.cs b/LinqStudy/Models/HometownEqualityComparer.cs new file mode 100644 index 0000000..6e1b397 --- /dev/null +++ b/LinqStudy/Models/HometownEqualityComparer.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; + +namespace LinqStudy +{ + /// + /// 家乡类 相等比较器 + /// + public class HometownEqualityComparer : IEqualityComparer + { + bool IEqualityComparer.Equals(Hometown x, Hometown y) + { + if (x==null || y==null) + { + return false; + } + + return x.Province == y.Province && x.City == y.City; + } + + int IEqualityComparer.GetHashCode(Hometown obj) + { + return (obj.Province+obj.City).GetHashCode(); + } + } +} diff --git a/LinqStudy/Models/Person.cs b/LinqStudy/Models/Person.cs index da45934..c2e8be5 100644 --- a/LinqStudy/Models/Person.cs +++ b/LinqStudy/Models/Person.cs @@ -3,7 +3,7 @@ using System; namespace LinqStudy { /// - /// + /// 人类 /// public class Person { diff --git a/LinqStudy/Models/PersonCompare.cs b/LinqStudy/Models/PersonCompare.cs index d2eec98..57541e6 100644 --- a/LinqStudy/Models/PersonCompare.cs +++ b/LinqStudy/Models/PersonCompare.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; namespace LinqStudy { /// - /// PersonȽIdΪȽϱ׼ + /// Person 比较器 /// public class PersonComparer : IComparer { diff --git a/LinqStudy/Models/PersonEqualityComparerByName.cs b/LinqStudy/Models/PersonEqualityComparerByName.cs new file mode 100644 index 0000000..e9a4bf7 --- /dev/null +++ b/LinqStudy/Models/PersonEqualityComparerByName.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; + +namespace LinqStudy +{ + public class PersonEqualityComparerByName : IEqualityComparer + { + bool IEqualityComparer.Equals(Person x, Person y) + { + if (x==null || y==null) + { + return false; + } + + return x.Name == y.Name; + } + + int IEqualityComparer.GetHashCode(Person obj) + { + return (obj.Name).GetHashCode(); + } + } +} diff --git a/LinqStudy/Models/Teacher.cs b/LinqStudy/Models/Teacher.cs new file mode 100644 index 0000000..1cf33ca --- /dev/null +++ b/LinqStudy/Models/Teacher.cs @@ -0,0 +1,25 @@ +using System; + +namespace LinqStudy +{ + /// + /// 老师 + /// + public class Teacher + { + /// + /// Id + /// + public int Id {get;set;} + + /// + /// 姓名 + /// + public string Name{get;set;} + + /// + /// 家乡 + /// + public Hometown Hometown{get;set;} + } +} diff --git a/LinqStudy/Models/TeacherCompare.cs b/LinqStudy/Models/TeacherCompare.cs new file mode 100644 index 0000000..ca993ab --- /dev/null +++ b/LinqStudy/Models/TeacherCompare.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using LinqStudy; + +namespace LinqStudy +{ + /// + /// 家乡 比较器 + /// + public class TeacherCompare : IComparer + { + int IComparer.Compare(Teacher x, Teacher y) + { + int compareResult = 0; + + if (x == null && y == null) + { + compareResult = 0; + } + + else if (x == null) + { + compareResult = 1; + } + else if (y == null) + { + compareResult = -1; + } + else + { + if(x.Id == y.Id) + { + if(x.Name==y.Name) + { + IComparer homeCompare= new HometownCompare(); + compareResult= homeCompare.Compare(x.Hometown, y.Hometown); + } + else + { + compareResult = string.Compare(x.Name,y.Name); + } + + } + else + { + if(x.Id>y.Id) + { + compareResult =1; + } + else + { + compareResult = -1; + } + } + } + + return compareResult; + } + } +}