You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

382 lines
12 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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>
/// 重载2seed 自定初始值和“聚合项”类型
/// </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>
/// 重载3seed 自定初始值和“聚合项”类型
/// </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
}
}