LINQ学习之旅——第一站"LTO"之非延时标准查询操作符(下)

  紧接着昨天的内容,把剩余的几个非延时标准查询操作符讲解一下。

  12.ElementAt操作符

  (1)作用:用于返回序列中指定位置的元素;

  (2)方法原型

    public static T ElementAt<T>(

    this IEnumerable<T> source,

    int index);

  (3)原型说明:参数index用于指定元素在序列中的位置,位置索引以0开始,若指定的索引小于0或者大于或者等于序列中元素的个数,则操作符ElementAt抛出异常

  (4)示例验证

ElementAt操作符
 1 staticvoid Main(string[] args)
2 {
3 //定义雇员数组
4 Employee[] employees =new Employee[]
5 {
6 new Employee{Id="0001",Name="张三",Age=32},
7 new Employee{Id="0002",Name="李四",Age=31},
8 new Employee{Id="0003",Name="王五",Age=32},
9 new Employee{Id="0004",Name="小六",Age=25},
10 new Employee{Id="0005",Name="张麻子",Age=40},
11 new Employee{Id="0006",Name="王小二",Age=25},
12 new Employee{Id="0007",Name="灭绝师太",Age=55},
13 };
14
15 Console.WriteLine("调用Element操作符:");
16 Console.WriteLine("------------------------------------");
17
18 Employee employee = employees.ElementAt(4);
19
20 Console.WriteLine("雇员序列中的索引为4的元素:");
21 Console.WriteLine(employee.ToString());
22
23 Console.Read();
24 }

结果

  13.ElementAtOrDefault操作符

  (1)作用:用于返回序列中指定位置的元素,如果指定索引的值不合法,则返回一个相关类型默认值元素;

  (2)方法原型

    public static T ElementAtOrDefault<T>(

    this IEnumerable<T> source,

    int index);

  (3)原型说明:实现原理和操作符ElementAt一样,唯一区别在当索引值小于0或者大于或者等于序列中元素个数时,即索引值非法情况,操作符ElementAt会抛出异常。而操作符ElementAtOrDefault则返回T类型的默认值default(T)

  (4)示例验证

ElementAtOrDefault操作符
 1 staticvoid Main(string[] args)
2 {
3 //定义雇员数组
4 Employee[] employees =new Employee[]
5 {
6 new Employee{Id="0001",Name="张三",Age=32},
7 new Employee{Id="0002",Name="李四",Age=31},
8 new Employee{Id="0003",Name="王五",Age=32},
9 new Employee{Id="0004",Name="小六",Age=25},
10 new Employee{Id="0005",Name="张麻子",Age=40},
11 new Employee{Id="0006",Name="王小二",Age=25},
12 new Employee{Id="0007",Name="灭绝师太",Age=55},
13 };
14
15 Console.WriteLine("调用ElementAtOrDefault操作符:");
16 Console.WriteLine("------------------------------------");
17
18 Employee employee1 = employees.ElementAtOrDefault(7);
19
20 Console.WriteLine("雇员序列中的索引为7的元素:");
21 Console.WriteLine(employee1);
22
23 Console.Read();
24 }

结果

  14.Any操作符

  (1)作用:判断输入序列中是否含有元素或者含有满足条件的元素;

  (2)方法原型

    ①原型定义:

    public static bool Any<T>(

    this IEnumerable<T> source); 

    ②原型定义:

    public static bool Any<T>(

    this IEnumerable<T> source,

    Func<T,bool> predicate); 

  (3)原型说明:第一种方法原型接收一个输入序列source,如果序列中至少有一个元素,操作符返回true,否则false。第二种原型比前一种多了一个委托参数predicate,只要至少有一个元素使得委托predicate的返回值为true,则操作符Any返回值就为true,否则为false;

  (4)示例验证

Any操作符
 1 staticvoid Main(string[] args)
2 {
3 //定义雇员数组
4 Employee[] employees =new Employee[]
5 {
6 new Employee{Id="0001",Name="张三",Age=32},
7 new Employee{Id="0002",Name="李四",Age=31},
8 new Employee{Id="0003",Name="王五",Age=32},
9 new Employee{Id="0004",Name="小六",Age=25},
10 new Employee{Id="0005",Name="张麻子",Age=40},
11 new Employee{Id="0006",Name="王小二",Age=25},
12 new Employee{Id="0007",Name="灭绝师太",Age=55},
13 };
14
15 //Any第一个原型
16 Console.WriteLine("调用Any操作符第一个方法原型:");
17 Console.WriteLine("------------------------------------");
18
19 bool flag = employees.Any();
20 if (flag)
21 Console.WriteLine("雇员序列中至少有一个元素!");
22 else
23 Console.WriteLine("雇员序列为空!");
24
25 Console.WriteLine("***************************************************");
26
27 //Any第二个原型
28 Console.WriteLine("调用Any操作符第二个方法原型:");
29 Console.WriteLine("------------------------------------");
30
31 bool flag1 = employees.Any(e=>e.Id=="0005");
32 if (flag1)
33 Console.WriteLine("至少有一个0005号雇员!");
34 else
35 Console.WriteLine("没有0005好雇员!");
36
37 Console.Read();
38 }

结果

  15.All操作符

  (1)作用:用于判断输入序列中所有元素是否都满足指定条件;

  (2)方法原型

    public static bool All<T>(

    this IEnumerable<T> source,

    Func<T,bool> predicate); 

  (3)原型说明:在调用操作符All时,系统把输入序列source中的每一个元素作为参数传递给委托predicate,只有输入序列中所有的元素都能使得委托predicate返回值为true,那么All操作符返回true,否者返回false;

  (4)示例验证

All操作符
 1 //定义雇员数组
2 Employee[] employees =new Employee[]
3 {
4 new Employee{Id="0001",Name="张三",Age=32},
5 new Employee{Id="0002",Name="李四",Age=31},
6 new Employee{Id="0003",Name="王五",Age=32},
7 new Employee{Id="0004",Name="小六",Age=25},
8 new Employee{Id="0005",Name="张麻子",Age=40},
9 new Employee{Id="0006",Name="王小二",Age=25},
10 new Employee{Id="0007",Name="灭绝师太",Age=55},
11 };
12
13 Console.WriteLine("调用All操作符:");
14 Console.WriteLine("------------------------------------");
15
16 bool flag2 = employees.All(e => e.Age <60);
17
18 if (flag2)
19 Console.WriteLine("没有年龄超过60的雇员!");
20 else
21 Console.WriteLine("有年龄大于等于60的雇员!");
22
23 Console.Read();
24 }

结果

  16.Contains操作符

  (1)作用:用于判断输入序列中是否含有指定元素;

  (2)方法原型

    ①原型定义:

    public static bool Contains<T>(

    this IEnumerable<T> source,

    T value); 

    ②原型定义:

    public static bool Contains<T>(

    this IEnumerable<T> source,

    T value,

    IEqulityComparer<T> Comparer); 

  (3)原型说明:在调用操作符contains时,系统将在输入序列中查找与value相等的元素。若找到则返回true,否者返回false。相比较第一种方法原型,第二种方法多了一个类型为IEqulityComparer<T> 的参数,它能让开发人员自定义相等比较逻辑来对输入序列中的元素和参数value作相等比较。而第一种原型用的是EqulityComparer<T>.Default实现的相等比较;

  (4)示例验证

①自定义雇员名字比较类

雇员名字比较类
 1 //雇员名字比较类
2 publicclass EmployeeNameComparer:IEqualityComparer<string>
3 {
4 publicbool Equals(string name1, string name2)
5 {
6 return name1 == name2;
7 }
8
9 publicint GetHashCode(string name)
10 {
11 return name.GetHashCode();
12 }
13 }

②调用操作符Contains

Contains操作符
 1 staticvoid Main(string[] args)
2 {
3 //定义雇员数组
4 Employee[] employees =new Employee[]
5 {
6 new Employee{Id="0001",Name="张三",Age=32},
7 new Employee{Id="0002",Name="李四",Age=31},
8 new Employee{Id="0003",Name="王五",Age=32},
9 new Employee{Id="0004",Name="小六",Age=25},
10 new Employee{Id="0005",Name="张麻子",Age=40},
11 new Employee{Id="0006",Name="王小二",Age=25},
12 new Employee{Id="0007",Name="灭绝师太",Age=55},
13 };
14
15 //Contains第一个原型
16 Console.WriteLine("调用Contains操作符第一个方法原型:");
17 Console.WriteLine("------------------------------------");
18
19 bool flag3 = employees.Select(e => e.Age).Contains(55);
20 if (flag3)
21 Console.WriteLine("序列中含有年龄为55的雇员!");
22 else
23 Console.WriteLine("雇员中没有年龄为55的雇员!");
24
25 Console.WriteLine("***************************************************");
26
27 //Contains第二个原型
28 Console.WriteLine("调用Contains操作符第二个方法原型:");
29 Console.WriteLine("------------------------------------");
30
31 //生成一个雇员名字比较类的辅助对象
32 EmployeeNameComparer enc=new EmployeeNameComparer();
33
34 bool flag4 = employees.Select(e => e.Name).Contains("张麻子", enc);
35 if (flag4)
36 Console.WriteLine("雇员中有名为张麻子的!(含有辅助比较对象)");
37 else
38 Console.WriteLine("雇员中没有名为张麻子的!(含有辅助比较对象)");
39
40 Console.Read();
41 }

③结果

  17.Count操作符

  (1)作用:用于计算输入序列的元素个数或满足特定条件的元素个数;

  (2)方法原型

    ①原型定义:

    public static int Count<T>(

    this IEnumerable<T> source); 

    ②原型定义:

    public static int Count<T>(

    this IEnumerable<T> source,

      Func<T,bool> predicate); 

  (3)原型说明:相比于第一种原型方法,第二种多了一个委托参数predicate,在调用操作符Count时,系统将输入序列中的每一个元素作为参数传递给委托predicate,所有使得委托predicate返回值为true的元素的个数被作为返回结果;

  (4)示例验证

Count操作符
 1 staticvoid Main(string[] args)
2 {
3 //定义雇员数组
4 Employee[] employees =new Employee[]
5 {
6 new Employee{Id="0001",Name="张三",Age=32},
7 new Employee{Id="0002",Name="李四",Age=31},
8 new Employee{Id="0003",Name="王五",Age=32},
9 new Employee{Id="0004",Name="小六",Age=25},
10 new Employee{Id="0005",Name="张麻子",Age=40},
11 new Employee{Id="0006",Name="王小二",Age=25},
12 new Employee{Id="0007",Name="灭绝师太",Age=55},
13 };
14
15 //Count第一个原型
16 Console.WriteLine("调用Count操作符第一个方法原型:");
17 Console.WriteLine("------------------------------------");
18
19 int count = employees.Count();
20
21 Console.WriteLine("雇员数为:{0}",count);
22
23 Console.WriteLine("***************************************************");
24
25 //Count第二个原型
26 Console.WriteLine("调用Count操作符第二个方法原型:");
27 Console.WriteLine("------------------------------------");
28
29 int count1 = employees.Count(e=>e.Age>30);
30
31 Console.WriteLine("年龄大于30的雇员数为:{0}", count1);
32
33 Console.Read();
34 }

结果

  18.LongCount操作符

  (1)作用:用于计算输入序列的元素个数或满足特定条件的元素个数;

  (2)方法原型

    ①原型定义:

    public static long LongCount<T>(

    this IEnumerable<T> source); 

    ②原型定义:

    public static long LongCount<T>(

    this IEnumerable<T> source,

      Func<T,bool> predicate); 

  (3)原型说明:原型定义和实现原理和操作符Count相同,唯一区别在于Count操作符返回值为int类型,LongCount操作符返回值为long类型;

  (4)示例验证:略;

  19.Sum操作符

  (1)作用:用于计算输入序列中所有元素数值总和;

  (2)方法原型

    ①原型定义:

    public static Numeric Sum(

    this IEnumerable<Numeric > source);

    ②原型定义:

    public static Numeric Sum<T>(

    this IEnumerable<T> source,

    Func<T,Numeric> selector);

  (3)原型说明:要注意的是第一种方法原型的输入序列中的元素类型只能是int、long、double和decimal的等数值类型。而第二种方法就不要求输入序列中的元素一定要为数值型的,其中委托参数selector,就是把输入序列中每一个元素传递给它,委托selector一次返回元素中的数值,再把这些数值求和返回;

  (4)示例验证

Sum操作符
 1 staticvoid Main(string[] args)
2 {
3 //定义雇员薪水数组
4 Salary[] salarys =new Salary[]
5 {
6 new Salary{EmployeeId="0001",Wage=1700,Bonus=2500,SalaryTime=new DateTime(2011,7,15)},
7 new Salary{EmployeeId="0002",Wage=1500,Bonus=2500,SalaryTime=new DateTime(2011,7,15)},
8 new Salary{EmployeeId="0003",Wage=1700,Bonus=3000,SalaryTime=new DateTime(2011,7,15)},
9 new Salary{EmployeeId="0004",Wage=1000,Bonus=2000,SalaryTime=new DateTime(2011,7,15)},
10 new Salary{EmployeeId="0005",Wage=2000,Bonus=4000,SalaryTime=new DateTime(2011,7,15)},
11 new Salary{EmployeeId="0006",Wage=1000,Bonus=2000,SalaryTime=new DateTime(2011,7,15)},
12 new Salary{EmployeeId="0007",Wage=3000,Bonus=5000,SalaryTime=new DateTime(2011,7,15)},
13 new Salary{EmployeeId="0001",Wage=1700,Bonus=3000,SalaryTime=new DateTime(2011,8,15)},
14 new Salary{EmployeeId="0002",Wage=1500,Bonus=3000,SalaryTime=new DateTime(2011,8,15)},
15 new Salary{EmployeeId="0003",Wage=1700,Bonus=4000,SalaryTime=new DateTime(2011,8,15)},
16 };
17
18 //Sum第一个原型
19 Console.WriteLine("调用Sum操作符第一个方法原型:");
20 Console.WriteLine("------------------------------------");
21
22 double wagesum= salarys.Select(s => s.Wage).Sum();
23
24 Console.WriteLine("总共发出工资数:{0}", wagesum);
25
26 Console.WriteLine("***************************************************");
27
28 //Sum第二个原型
29 Console.WriteLine("调用Sum操作符第二个方法原型:");
30 Console.WriteLine("------------------------------------");
31
32 var list= salarys.GroupBy(s=>s.EmployeeId).Select(ss=>new {EmployeeId=ss.Key,WageCount=ss.Sum(s=>s.Wage),BounsCount=ss.Sum(s=>s.Bonus)});
33
34 Console.WriteLine("每个雇员发放薪水的总和情况:");
35 foreach (var s in list)
36 {
37 Console.WriteLine(s);
38 }
39
40 Console.Read();
41 }

结果

  20.Min操作符

  (1)作用:用于获取输入序列中所有元素的最小值;

  (2)方法原型

    ①原型定义:

    public static Numeric Min(

    this IEnumerable<Numeric > source);

    ②原型定义:

    public static Numeric Min<T>(

    this IEnumerable<T> source,

    Func<T,Numeric> selector);

    ③原型定义:

    public static T Min<T>(

    this IEnumerable<T> source);

    ④原型定义:

    public static S Min<T,S>(

    this IEnumerable<T> source,

    Func<T,S> selector);

  (3)原型说明:同样的,操作符Min的第一种方法原型的输入序列中的元素类型只能是int、long、double和decimal的等数值类型而第二种方法就不要求输入序列中的元素一定要为数值型的,其中委托参数selector,就是把输入序列中每一个元素传递给它,委托selector一次返回元素中的数值,再从这些数值中返回最小的一个。第三种方法原型允许一个非数值型元素组成的序列中查找最小值,系统将使用IComparable<T>接口或IComparable接口的方法来比较元素大小。最后一种方法原型比第三种原型多了一个委托参数,系统把输入序列source中每一个元素作为参数传递给委托selector,委托selector根据输入参数一次返回类型为S的对象,接着从这些对象中返回最小的一个;

  (4)示例验证

Min操作符
 1 staticvoid Main(string[] args)
2 {
3 //定义雇员数组
4 Employee[] employees =new Employee[]
5 {
6 new Employee{Id="0001",Name="张三",Age=32},
7 new Employee{Id="0002",Name="李四",Age=31},
8 new Employee{Id="0003",Name="王五",Age=32},
9 new Employee{Id="0004",Name="小六",Age=25},
10 new Employee{Id="0005",Name="张麻子",Age=40},
11 new Employee{Id="0006",Name="王小二",Age=25},
12 new Employee{Id="0007",Name="灭绝师太",Age=55},
13 };
14
15 //定义雇员薪水数组
16 Salary[] salarys =new Salary[]
17 {
18 new Salary{EmployeeId="0001",Wage=1700,Bonus=2500,SalaryTime=new DateTime(2011,7,15)},
19 new Salary{EmployeeId="0002",Wage=1500,Bonus=2500,SalaryTime=new DateTime(2011,7,15)},
20 new Salary{EmployeeId="0003",Wage=1700,Bonus=3000,SalaryTime=new DateTime(2011,7,15)},
21 new Salary{EmployeeId="0004",Wage=1000,Bonus=2000,SalaryTime=new DateTime(2011,7,15)},
22 new Salary{EmployeeId="0005",Wage=2000,Bonus=4000,SalaryTime=new DateTime(2011,7,15)},
23 new Salary{EmployeeId="0006",Wage=1000,Bonus=2000,SalaryTime=new DateTime(2011,7,15)},
24 new Salary{EmployeeId="0007",Wage=3000,Bonus=5000,SalaryTime=new DateTime(2011,7,15)},
25 new Salary{EmployeeId="0001",Wage=1700,Bonus=3000,SalaryTime=new DateTime(2011,8,15)},
26 new Salary{EmployeeId="0002",Wage=1500,Bonus=3000,SalaryTime=new DateTime(2011,8,15)},
27 new Salary{EmployeeId="0003",Wage=1700,Bonus=4000,SalaryTime=new DateTime(2011,8,15)},
28 };
29
30 //Min第一个原型
31 Console.WriteLine("调用Min操作符第一个方法原型:");
32 Console.WriteLine("------------------------------------");
33
34 double minwage = salarys.Select(s => s.Wage).Min();
35
36 Console.WriteLine("最低工资:{0}", minwage);
37
38 Console.WriteLine("***************************************************");
39
40 //Min第二个原型
41 Console.WriteLine("调用Min操作符第二个方法原型:");
42 Console.WriteLine("------------------------------------");
43
44 double minsalarycount = salarys.ToDictionary(s =>new { s.EmployeeId, s.SalaryTime }).Min(s=>s.Value.Bonus+s.Value.Wage);
45
46 Console.WriteLine("薪水的总和最低:{0}",minsalarycount);
47
48 Console.WriteLine("***************************************************");
49
50 //Min第三个原型
51 Console.WriteLine("调用Min操作符第三个方法原型:");
52 Console.WriteLine("------------------------------------");
53
54 string employeename = employees.Select(e => e.Name).Min();
55
56 Console.WriteLine("按字符排序的雇员名最小值:{0}",employeename);
57
58 Console.WriteLine("***************************************************");
59
60 //Min第四个原型
61 Console.WriteLine("调用Min操作符第四个方法原型:");
62 Console.WriteLine("------------------------------------");
63
64 string employeename1 = employees.Min(e => e.Name);
65
66 Console.WriteLine("按字符排序的雇员名最小值:{0}", employeename1);
67
68 Console.Read();
69 }

结果

  21.Max操作符

  (1)作用:用于获取输入序列中所有元素的最大值;

  (2)方法原型: 

    ①原型定义:

    public static Numeric Max(

    this IEnumerable<Numeric > source);

    ②原型定义:

    public static Numeric Max<T>(

    this IEnumerable<T> source,

    Func<T,Numeric> selector);

    ③原型定义:

    public static T Max<T>(

    this IEnumerable<T> source);

    ④原型定义:

    public static S Max<T,S>(

    this IEnumerable<T> source,

    Func<T,S> selector);

  (3)原型说明:四种方法原型和Min操作符一样,实现方法也相同,唯一区别在于Max操作符求最大值,Min操作符求最小值;

  (4)示例验证

Max操作符
 1 staticvoid Main(string[] args)
2 {
3 //定义雇员数组
4 Employee[] employees =new Employee[]
5 {
6 new Employee{Id="0001",Name="张三",Age=32},
7 new Employee{Id="0002",Name="李四",Age=31},
8 new Employee{Id="0003",Name="王五",Age=32},
9 new Employee{Id="0004",Name="小六",Age=25},
10 new Employee{Id="0005",Name="张麻子",Age=40},
11 new Employee{Id="0006",Name="王小二",Age=25},
12 new Employee{Id="0007",Name="灭绝师太",Age=55},
13 };
14
15 //定义雇员薪水数组
16 Salary[] salarys =new Salary[]
17 {
18 new Salary{EmployeeId="0001",Wage=1700,Bonus=2500,SalaryTime=new DateTime(2011,7,15)},
19 new Salary{EmployeeId="0002",Wage=1500,Bonus=2500,SalaryTime=new DateTime(2011,7,15)},
20 new Salary{EmployeeId="0003",Wage=1700,Bonus=3000,SalaryTime=new DateTime(2011,7,15)},
21 new Salary{EmployeeId="0004",Wage=1000,Bonus=2000,SalaryTime=new DateTime(2011,7,15)},
22 new Salary{EmployeeId="0005",Wage=2000,Bonus=4000,SalaryTime=new DateTime(2011,7,15)},
23 new Salary{EmployeeId="0006",Wage=1000,Bonus=2000,SalaryTime=new DateTime(2011,7,15)},
24 new Salary{EmployeeId="0007",Wage=3000,Bonus=5000,SalaryTime=new DateTime(2011,7,15)},
25 new Salary{EmployeeId="0001",Wage=1700,Bonus=3000,SalaryTime=new DateTime(2011,8,15)},
26 new Salary{EmployeeId="0002",Wage=1500,Bonus=3000,SalaryTime=new DateTime(2011,8,15)},
27 new Salary{EmployeeId="0003",Wage=1700,Bonus=4000,SalaryTime=new DateTime(2011,8,15)},
28 };
29
30 //Max第一个原型
31 Console.WriteLine("调用Max操作符第一个方法原型:");
32 Console.WriteLine("------------------------------------");
33
34 double maxwage = salarys.Select(s => s.Wage).Max();
35
36 Console.WriteLine("最高工资:{0}", maxwage);
37
38 Console.WriteLine("***************************************************");
39
40 //Max第二个原型
41 Console.WriteLine("调用Max操作符第二个方法原型:");
42 Console.WriteLine("------------------------------------");
43
44 double maxsalarycount = salarys.ToDictionary(s =>new { s.EmployeeId, s.SalaryTime }).Max(s => s.Value.Bonus + s.Value.Wage);
45
46 Console.WriteLine("薪水的总和最高:{0}", maxsalarycount);
47
48 Console.WriteLine("***************************************************");
49
50 //Max第三个原型
51 Console.WriteLine("调用Max操作符第三个方法原型:");
52 Console.WriteLine("------------------------------------");
53
54 string employeename2 = employees.Select(e => e.Name).Max();
55
56 Console.WriteLine("按字符排序的雇员名最大值:{0}", employeename2);
57
58 Console.WriteLine("***************************************************");
59
60 //Max第四个原型
61 Console.WriteLine("调用Max操作符第四个方法原型:");
62 Console.WriteLine("------------------------------------");
63
64 string employeename3 = employees.Max(e => e.Name);
65
66 Console.WriteLine("按字符排序的雇员名最大值:{0}", employeename3);
67
68 Console.Read();
69 }

结果

  22.Average操作符

  (1)作用:用于计算输入序列中所有元素的平均值;

  (2)方法原型

    ①原型定义:

    public static Result Average(

    this IEnumerable<Numeric > source);

    ②原型定义:

    public static Result Average<T>(

    this IEnumerable<T> source,

    Func<T,Numeric> selector);

  (3)原型说明:和Sum操作符一样,第一种方法原型的输入序列中的元素类型只能是int、long、double和decimal的等数值类型。且返回的Result代表一种对应的数值类型,而第二种方法就不要求输入序列中的元素一定要为数值型的,其中委托参数selector,就是把输入序列中每一个元素传递给它,委托selector一次返回元素中的数值,再把这些数值求平均值返回;

  (4)示例验证

Average操作符
 1 staticvoid Main(string[] args)
2 {
3 //定义雇员薪水数组
4 Salary[] salarys =new Salary[]
5 {
6 new Salary{EmployeeId="0001",Wage=1700,Bonus=2500,SalaryTime=new DateTime(2011,7,15)},
7 new Salary{EmployeeId="0002",Wage=1500,Bonus=2500,SalaryTime=new DateTime(2011,7,15)},
8 new Salary{EmployeeId="0003",Wage=1700,Bonus=3000,SalaryTime=new DateTime(2011,7,15)},
9 new Salary{EmployeeId="0004",Wage=1000,Bonus=2000,SalaryTime=new DateTime(2011,7,15)},
10 new Salary{EmployeeId="0005",Wage=2000,Bonus=4000,SalaryTime=new DateTime(2011,7,15)},
11 new Salary{EmployeeId="0006",Wage=1000,Bonus=2000,SalaryTime=new DateTime(2011,7,15)},
12 new Salary{EmployeeId="0007",Wage=3000,Bonus=5000,SalaryTime=new DateTime(2011,7,15)},
13 new Salary{EmployeeId="0001",Wage=1700,Bonus=3000,SalaryTime=new DateTime(2011,8,15)},
14 new Salary{EmployeeId="0002",Wage=1500,Bonus=3000,SalaryTime=new DateTime(2011,8,15)},
15 new Salary{EmployeeId="0003",Wage=1700,Bonus=4000,SalaryTime=new DateTime(2011,8,15)},
16 };
17
18 //Average第一个原型
19 Console.WriteLine("调用Average操作符第一个方法原型:");
20 Console.WriteLine("------------------------------------");
21
22 double avewage = salarys.Select(s => s.Wage).Average();
23
24 Console.WriteLine("平均工资:{0}", avewage);
25
26 Console.WriteLine("***************************************************");
27
28 //Average第二个原型
29 Console.WriteLine("调用Average操作符第二个方法原型:");
30 Console.WriteLine("------------------------------------");
31
32 var list1 = salarys.GroupBy(s => s.EmployeeId).Select(ss =>new { EmployeeId = ss.Key, AveWage = ss.Average(s => s.Wage), AveBonus = ss.Average(s => s.Bonus) });
33
34 Console.WriteLine("每个雇员的平均薪水:");
35 foreach (var s in list1)
36 {
37 Console.WriteLine(s);
38 }
39
40 Console.Read();
41 }

结果

  23.Aggregate操作符

  (1)作用:用于在输入序列的所有元素上累积执行某个特定的方法;

  (2)方法原型

    ①原型定义:

    public static T Aggregate<T>(

    this IEnumerable<T> source,

    Func<T,T,T> func);

    ②原型定义:

    public static U Aggregate<T,U>(

    this IEnumerable<T> source,

    U seed,

    Func<U,T,U> func);

  (3)原型说明:第一种方法原型中的委托参数func接收两个类型为T的输入参数,返回一个类型为T的结果。当操作符Aggregate被调用时,系统将输入序列中的元素和委托func的上一次执行的结果一起作为委托func的输入参数,委托func根据这两个参数计算出结果,再和下一个输入序列元素一起作为委托func的两个输入参数,就这样依次迭代,直到最后一次调用委托func返回结果。其中要注意的是第一次调用委托func时,只是传递输入序列中的元素一个参数。相比较于第一种方法原型,第二种多了一个参数seed,它主要用于当系统第一次调用委托func时,第二种原型方法把输入序列中的元素和参数seed两个参数传递给委托func。而第一种方法只是传递输入序列的元素一个参数给委托func;

  (4)示例验证

Aggregate操作符
 1 staticvoid Main(string[] args)
2 {
3 //定义雇员薪水数组
4 Salary[] salarys =new Salary[]
5 {
6 new Salary{EmployeeId="0001",Wage=1700,Bonus=2500,SalaryTime=new DateTime(2011,7,15)},
7 new Salary{EmployeeId="0002",Wage=1500,Bonus=2500,SalaryTime=new DateTime(2011,7,15)},
8 new Salary{EmployeeId="0003",Wage=1700,Bonus=3000,SalaryTime=new DateTime(2011,7,15)},
9 new Salary{EmployeeId="0004",Wage=1000,Bonus=2000,SalaryTime=new DateTime(2011,7,15)},
10 new Salary{EmployeeId="0005",Wage=2000,Bonus=4000,SalaryTime=new DateTime(2011,7,15)},
11 new Salary{EmployeeId="0006",Wage=1000,Bonus=2000,SalaryTime=new DateTime(2011,7,15)},
12 new Salary{EmployeeId="0007",Wage=3000,Bonus=5000,SalaryTime=new DateTime(2011,7,15)},
13 new Salary{EmployeeId="0001",Wage=1700,Bonus=3000,SalaryTime=new DateTime(2011,8,15)},
14 new Salary{EmployeeId="0002",Wage=1500,Bonus=3000,SalaryTime=new DateTime(2011,8,15)},
15 new Salary{EmployeeId="0003",Wage=1700,Bonus=4000,SalaryTime=new DateTime(2011,8,15)},
16 };
17
18 //Aggregate第一个原型
19 Console.WriteLine("调用Aggregate操作符第一个方法原型:");
20 Console.WriteLine("------------------------------------");
21
22 double bonuscount = salarys.Select(s => s.Bonus).Aggregate((result, next) => result + next);
23
24 Console.WriteLine("发放的总奖金:{0}", bonuscount);
25
26 Console.WriteLine("***************************************************");
27
28 //Aggregate第二个原型
29 Console.WriteLine("调用Aggregate操作符第二个方法原型:");
30 Console.WriteLine("------------------------------------");
31
32 double bonuscount1 = salarys.Select(s => s.Bonus).Aggregate(0,(result, next) =>Convert.ToInt32(result + next));//注:委托返回值类型和参数seed的类型要相同
33
34 Console.WriteLine("发放的总奖金:{0}", bonuscount1);
35
36 Console.Read();
37 }

结果

posted @ 2011-09-04 13:54  Rookie_J  阅读(971)  评论(2编辑  收藏  举报