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
}
}