diff --git a/LinqStudy.Test/LinqToObject/AggregationTest.cs b/LinqStudy.Test/LinqToObject/AggregationTest.cs new file mode 100644 index 0000000..75fd773 --- /dev/null +++ b/LinqStudy.Test/LinqToObject/AggregationTest.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Linq; + +using Xunit; + +namespace LinqStudy.Test.LinqToObject +{ + /// + /// 聚合操作符:所有聚合操作是“立即执行”,不再一一测试。 + /// + public class AggregationTest + { + #region Aggregate + + /// + /// Aggregate:自定义聚合计算,是聚合计算的“基础”。所有聚合操作均是“立即执行”。 + /// 选择序列中的第一项(或自定义参数)为初始“聚合项”,“聚合项”作为输入项与序列中的下一项进行“聚合”操作,返回新的“聚合项”; + /// 新的“聚合项”与下一项继续“聚合”,直到序列中所有项都完成“聚合操作”,返回最后的“聚合项”。 + /// + [Fact] + public void Aggregate_default_Test() + { + List peoples = new List() + { + new Person(){ Id=1, Name="张三丰", Age=230}, + new Person(){ Id=2, Name="小龙女", Age=28}, + new Person(){ Id=3, Name="银花公主", Age=16}, + new Person(){ Id=4, Name="杨过", Age=32}, + //new Person(){ Id=5, Name="东方不败", Age=86}, + //new Person(){ Id=6, Name="金轮法王", Age=64}, + //new Person(){ Id=7, Name="周伯通", Age=98}, + //new Person(){ Id=8, Name="洪七公", Age=97}, + //new Person(){ Id=9, Name="郭靖", Age=63}, + //new Person(){ Id=10, Name="黄蓉", Age=59}, + }; + + //默认第一项作为"初始聚合项",即首次聚合操作,第一项作为“聚合项”输入与第二项聚合,一共“聚合”3次。 + //第1次:第1项作为“聚合项”与第2项“聚合”,返回新“聚合项”作为下次“聚合操作的”的“聚合项”参数; + //第2次:第1次返回的“聚合项”与第3项“聚合”,返回新“聚合项”; + //第3次:第2次返回的“聚合项”与第4项“聚合”,返回新“聚合项”; + // 由于第4项是最后一项,整个“聚合操作”结束,返回本次“聚合项”作为最后的输出。 + var agg = peoples.Aggregate + ( + (aggregateItem, next) => + { + //把当前元素的年龄加到返回的“聚合项”的年龄, + //最后的聚合项的年龄就是“总年龄”。 + //虽然可以使用Sum()直接得到总年龄,但Sum内容也是一样“算法”,只是特例化了。 + //Aggregate是整个聚合操作的基础,也是最为灵活的一个。 + next.Age = next.Age + aggregateItem.Age; + return next; + } + ); + + var totalAge = agg.Age; + var expectedAge = 230 + 28 + 16 + 32; + + Assert.Equal(expectedAge, totalAge); + } + + /// + /// 重载2:seed 自定初始值和“聚合项”类型 + /// + [Fact] + public void Aggregate_seed_func_Test() + { + List peoples = new List() + { + new Person(){ Id=1, Name="张三丰", Age=230}, + new Person(){ Id=2, Name="小龙女", Age=28}, + new Person(){ Id=3, Name="银花公主", Age=16}, + new Person(){ Id=4, Name="杨过", Age=32}, + }; + + var seed =0; + + //因为指定了初始聚合项,一共执行了4次“聚合操作”即每一项执行一次“聚合操作” + var agg = peoples.Aggregate + ( + seed, + (accumulate, currentItem) => + { + return accumulate + currentItem.Age; + } + ) ; + + var totalAge = agg; + var expectedAge = 230 + 28 + 16 + 32; + + Assert.Equal(expectedAge, totalAge); + } + + /// + /// 重载3:seed 自定初始值和“聚合项”类型 + /// + [Fact] + public void Aggregate_seed_func_resultSelector_Test() + { + List peoples = new List() + { + new Person(){ Id=1, Name="张三丰", Age=230}, + new Person(){ Id=2, Name="小龙女", Age=28}, + new Person(){ Id=3, Name="银花公主", Age=16}, + new Person(){ Id=4, Name="杨过", Age=32}, + }; + + var seed = 0; + + //因为指定了初始聚合项,一共执行了4次“聚合操作”即每一项执行一次“聚合操作” + var agg = peoples.Aggregate + ( + //种子项 + seed, + + //聚合操作 + (accumulateItem, currentItem) => + { + return accumulateItem + currentItem.Age; + }, + + //改变最后聚合结果,并返回。 + accumulateItem => "总年龄为:"+ accumulateItem.ToString() + ); + + var totalAge = agg; + var expectedAge = "总年龄为:"+ (230 + 28 + 16 + 32).ToString(); + + Assert.Equal(expectedAge.ToString(), totalAge); + } + + /// + /// InvalidOperationException异常:序列少于1项时。 + /// + [Fact] + public void Aggregate_InvalidOperationException_Test() + { + List peoples = new List(); + + Action act =() => peoples.Aggregate + ( + (aggregateItem, next) => + { + next.Age = next.Age + aggregateItem.Age; + return next; + } + ); + + Assert.Throws(act); + } + #endregion + } +} diff --git a/LinqStudy.Test/LinqToObject/GroupTest.cs b/LinqStudy.Test/LinqToObject/GroupTest.cs index 732400d..2da2993 100644 --- a/LinqStudy.Test/LinqToObject/GroupTest.cs +++ b/LinqStudy.Test/LinqToObject/GroupTest.cs @@ -236,7 +236,7 @@ namespace LinqStudy.Test.LinqToObject .ToList(); var lastItem=group[2].FirstOrDefault(); - var expected="上海松江人"; + var expected="上海"; Assert.Equal(expected, lastItem); }