|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
|
|
|
|
using Xunit;
|
|
|
|
|
|
|
|
|
|
namespace LinqStudy.Test.LinqToObject
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 聚合操作符:所有聚合操作是“立即执行”,不再一一测试。
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class AggregationTest
|
|
|
|
|
{
|
|
|
|
|
#region Aggregate
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Aggregate:自定义聚合计算,是聚合计算的“基础”。所有聚合操作均是“立即执行”。
|
|
|
|
|
/// 选择序列中的第一项(或自定义参数)为初始“聚合项”,“聚合项”作为输入项与序列中的下一项进行“聚合”操作,返回新的“聚合项”;
|
|
|
|
|
/// 新的“聚合项”与下一项继续“聚合”,直到序列中所有项都完成“聚合操作”,返回最后的“聚合项”。
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Fact]
|
|
|
|
|
public void Aggregate_default_Test()
|
|
|
|
|
{
|
|
|
|
|
List<Person> peoples = new List<Person>()
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 重载2:seed 自定初始值和“聚合项”类型
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Fact]
|
|
|
|
|
public void Aggregate_seed_func_Test()
|
|
|
|
|
{
|
|
|
|
|
List<Person> peoples = new List<Person>()
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 重载3:seed 自定初始值和“聚合项”类型
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Fact]
|
|
|
|
|
public void Aggregate_seed_func_resultSelector_Test()
|
|
|
|
|
{
|
|
|
|
|
List<Person> peoples = new List<Person>()
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// InvalidOperationException异常:序列少于1项时。
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Fact]
|
|
|
|
|
public void Aggregate_InvalidOperationException_Test()
|
|
|
|
|
{
|
|
|
|
|
List<Person> peoples = new List<Person>();
|
|
|
|
|
|
|
|
|
|
Action act =() => peoples.Aggregate
|
|
|
|
|
(
|
|
|
|
|
(aggregateItem, next) =>
|
|
|
|
|
{
|
|
|
|
|
next.Age = next.Age + aggregateItem.Age;
|
|
|
|
|
return next;
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
Assert.Throws<InvalidOperationException>(act);
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Average
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Average:求平均值
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Fact]
|
|
|
|
|
public void Average_Default_Test()
|
|
|
|
|
{
|
|
|
|
|
List<Person> peoples = new List<Person>()
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Count:序列元素的数量(范围:Int32.MinValue 至 Int32.MaxValue)
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Fact]
|
|
|
|
|
public void Count_Default_Test()
|
|
|
|
|
{
|
|
|
|
|
List<Person> peoples = new List<Person>()
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 重载:predicate
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Fact]
|
|
|
|
|
public void Count_predicate_Test()
|
|
|
|
|
{
|
|
|
|
|
List<Person> peoples = new List<Person>()
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Count:序列元素的数量(范围超过:Int32.MaxValue),返回长整形。
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Fact]
|
|
|
|
|
public void LongCount_Default_Test()
|
|
|
|
|
{
|
|
|
|
|
List<Person> peoples = new List<Person>()
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 重载:predicate
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Fact]
|
|
|
|
|
public void LongCount_predicate_Test()
|
|
|
|
|
{
|
|
|
|
|
List<Person> peoples = new List<Person>()
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Max:最大值
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Fact]
|
|
|
|
|
public void Max_Default_Test()
|
|
|
|
|
{
|
|
|
|
|
List<Person> peoples = new List<Person>()
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// InvalidOperationException 异常
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Fact]
|
|
|
|
|
public void Max_InvalidOperationException_Test()
|
|
|
|
|
{
|
|
|
|
|
List<Person> peoples = new List<Person>()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Action act = () => peoples.Max(p => p.Age);
|
|
|
|
|
|
|
|
|
|
Assert.Throws<InvalidOperationException>(act);
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Min
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Min:最小值
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Fact]
|
|
|
|
|
public void Min_Default_Test()
|
|
|
|
|
{
|
|
|
|
|
List<Person> peoples = new List<Person>()
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// InvalidOperationException 异常
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Fact]
|
|
|
|
|
public void Min_InvalidOperationException_Test()
|
|
|
|
|
{
|
|
|
|
|
List<Person> peoples = new List<Person>()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Action act = () => peoples.Min(p => p.Age);
|
|
|
|
|
|
|
|
|
|
Assert.Throws<InvalidOperationException>(act);
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Sum
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Sum:最和
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Fact]
|
|
|
|
|
public void Sum_Default_Test()
|
|
|
|
|
{
|
|
|
|
|
List<Person> peoples = new List<Person>()
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// OverflowException 异常
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Fact]
|
|
|
|
|
public void Sum_OverflowException_Test()
|
|
|
|
|
{
|
|
|
|
|
List<Person> peoples = new List<Person>()
|
|
|
|
|
{
|
|
|
|
|
new Person(){ Id=2, Name="小龙女", Age=int.MaxValue},
|
|
|
|
|
new Person(){ Id=4, Name="杨过", Age=32},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Action act = () => peoples.Sum(p => p.Age);
|
|
|
|
|
|
|
|
|
|
Assert.Throws<OverflowException>(act);
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|