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 #region Average /// /// Average:求平均值 /// [Fact] public void Average_Default_Test() { List peoples = new List() { new Person(){ Id=2, Name="小龙女", Age=28}, new Person(){ Id=4, Name="杨过", Age=32}, }; var avgAge = peoples.Average(q => q.Age); var expected = (28 + 32) / 2; Assert.True(avgAge - expected < 0.5); } #endregion #region Count /// /// Count:序列元素的数量(范围:Int32.MinValue 至 Int32.MaxValue) /// [Fact] public void Count_Default_Test() { List peoples = new List() { new Person(){ Id=2, Name="小龙女", Age=28}, new Person(){ Id=4, Name="杨过", Age=32}, }; var count = peoples.Count(); var expected = 2; Assert.Equal(count, expected); } /// /// 重载:predicate /// [Fact] public void Count_predicate_Test() { List peoples = new List() { new Person(){ Id=2, Name="小龙女", Age=28}, new Person(){ Id=4, Name="杨过", Age=32}, }; var count = peoples.Count(p => p.Age > 28); var expected = 1; Assert.Equal(count, expected); } #endregion #region LongCount /// /// Count:序列元素的数量(范围超过:Int32.MaxValue),返回长整形。 /// [Fact] public void LongCount_Default_Test() { List peoples = new List() { new Person(){ Id=2, Name="小龙女", Age=28}, new Person(){ Id=4, Name="杨过", Age=32}, }; var count = peoples.LongCount(); var expected = 2; Assert.Equal(count, expected); } /// /// 重载:predicate /// [Fact] public void LongCount_predicate_Test() { List peoples = new List() { new Person(){ Id=2, Name="小龙女", Age=28}, new Person(){ Id=4, Name="杨过", Age=32}, }; var count = peoples.LongCount(p => p.Age > 28); var expected = 1; Assert.Equal(count, expected); } #endregion #region Max /// /// Max:最大值 /// [Fact] public void Max_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}, }; var queryMax = peoples.Max(p => p.Age); var expectedAge = 230; Assert.Equal(expectedAge, queryMax); } /// /// InvalidOperationException 异常 /// [Fact] public void Max_InvalidOperationException_Test() { List peoples = new List() { }; Action act = () => peoples.Max(p => p.Age); Assert.Throws(act); } #endregion #region Min /// /// Min:最小值 /// [Fact] public void Min_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}, }; var queryMin = peoples.Min(p => p.Age); var expectedAge = 16; Assert.Equal(expectedAge, queryMin); } /// /// InvalidOperationException 异常 /// [Fact] public void Min_InvalidOperationException_Test() { List peoples = new List() { }; Action act = () => peoples.Min(p => p.Age); Assert.Throws(act); } #endregion #region Sum /// /// Sum:最和 /// [Fact] public void Sum_Default_Test() { List peoples = new List() { new Person(){ Id=2, Name="小龙女", Age=28}, new Person(){ Id=4, Name="杨过", Age=32}, }; var querySum = peoples.Sum(p => p.Age); var expectedAge = 60; Assert.Equal(expectedAge, querySum); } /// /// OverflowException 异常 /// [Fact] public void Sum_OverflowException_Test() { List peoples = new List() { new Person(){ Id=2, Name="小龙女", Age=int.MaxValue}, new Person(){ Id=4, Name="杨过", Age=32}, }; Action act = () => peoples.Sum(p => p.Age); Assert.Throws(act); } #endregion } }