LINQ 聚合运算符 Aggregate

聚合运算符对集合中元素的数值属性执行数学运算,如Average、Aggregate、Count、Max、Min和Sum。

方法描述
Aggregate对集合中的值执行自定义聚合操作。
Average计算集合中数字项的平均值。
Count

统计集合中的元素。

LongCount

统计集合中的元素。

Max

查找集合中的最大值。

Min

查找集合中的最小值。

Sum计算集合中值的总和。

Aggregate

聚合方法执行累加操作。聚合扩展方法具有以下重载方法:

Aggregate()重载:

public static TSource Aggregate<TSource>(this IEnumerable<TSource> source, 
                                         Func<TSource, TSource, TSource> func);

public static TAccumulate Aggregate<TSource, TAccumulate>(this IEnumerable<TSource> source, 
                                         TAccumulate seed, 
                                         Func<TAccumulate, TSource, TAccumulate> func);

public static TResult Aggregate<TSource, TAccumulate, TResult>(this IEnumerable<TSource> source, 
                                         TAccumulate seed, 
                                         Func<TAccumulate, TSource, TAccumulate> func, 
                                         Func<TAccumulate, TResult> resultSelector);

下面的示例演示了 Aggregate 方法,该方法返回字符串列表中逗号分隔的元素。

IList<String> strList = new List<String>() { "One", "Two", "Three", "Four", "Five"};

var commaSeperatedString = strList.Aggregate((s1, s2) => s1 + ", " + s2);

Console.WriteLine(commaSeperatedString);
输出:
 One, Two, Three, Four, Five

在上面的示例中,Aggregate扩展方法从strList集合返回逗号分隔的字符串。下图说明了以上示例中执行的整个聚合操作。

聚合扩展方法

如上图所示,strList“ One”的第一项将作为 s1传递,其余项将作为 s2传递。Lambda 表达式(s1,s2) = > s1 + ","+ s2将被视为 s1 = s1 +","+ s1,其中 s1将为集合中的每个项累积。因此,Aggregate 方法将返回逗号分隔的字符串。

Dim strList As IList(Of String) = New List(Of String) From {
                                                            "One", 
                                                            "Two", 
                                                            "Three", 
                                                            "Four", 
                                                            "Five"
                                                        }

Dim commaSeparatedString = strList.Aggregate(Function(s1, s2) s1 + ", " + s2)

带种子值的聚合方法

Aggregate的第二个重载方法需要第一个参数来累积种子值。第二个参数是Func类型的委托:

TAccumulate Aggregate<TSource, TAccumulate>(TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func);

下面的示例在Aggregate扩展方法中将字符串用作种子值。

// 学生集合
IList<Student> studentList = new List<Student>>() { 
        new Student() { StudentID = 1, StudentName = "John", Age = 13} ,
        new Student() { StudentID = 2, StudentName = "Moin",  Age = 21 } ,
        new Student() { StudentID = 3, StudentName = "Bill",  Age = 18 } ,
        new Student() { StudentID = 4, StudentName = "Ram" , Age = 20} ,
        new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 } 
    };

string commaSeparatedStudentNames = studentList.Aggregate<Student, string>(
                                        "Student Names: ",  // 种子价值
                                        (str, s) => str += s.StudentName + "," ); 

Console.WriteLine(commaSeparatedStudentNames);
// 学生集合
Dim studentList = New List(Of Student) From {
        New Student() With {.StudentID = 1, .StudentName = "John", .Age = 13},
        New Student() With {.StudentID = 2, .StudentName = "Moin", .Age = 21},
        New Student() With {.StudentID = 3, .StudentName = "Bill", .Age = 18},
        New Student() With {.StudentID = 4, .StudentName = "Ram", .Age = 20},
        New Student() With {.StudentID = 5, .StudentName = "Ron", .Age = 15}
    }
 Dim commaSeparatedStudentNames = studentList.Aggregate(Of String)(
               "Student Names: ", 
               Function(str, s) str + s.StudentName + ",")

Console.WriteLine(commaSeparatedStudentNames);
输出:
Student Names: John, Moin, Bill, Ram, Ron,

在上面的示例中,Aggregate 方法的第一个参数是“ Student Names: ”字符串,该字符串将与所有学生名一起累积。Lambda 表达式中的逗号将作为第二个参数传递。

下面的示例使用 Aggregate 运算符添加所有学生的年龄。

// 学生集合
IList<Student> studentList = new List<Student>>() { 
        new Student() { StudentID = 1, StudentName = "John", Age = 13} ,
        new Student() { StudentID = 2, StudentName = "Moin",  Age = 21 } ,
        new Student() { StudentID = 3, StudentName = "Bill",  Age = 18 } ,
        new Student() { StudentID = 4, StudentName = "Ram" , Age = 20} ,
        new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 } 
    };

int SumOfStudentsAge = studentList.Aggregate<Student, int>(0, 
                                                (totalAge, s) => totalAge += s.Age  );

带有结果选择器的聚合方法

现在,让我们看看第三个重载方法,它需要 Func 委托表达式的第三个参数作为结果选择器,这样您就可以公式化结果。

IList<Student> studentList = new List<Student>>() { 
        new Student() { StudentID = 1, StudentName = "John", Age = 13} ,
        new Student() { StudentID = 2, StudentName = "Moin",  Age = 21 } ,
        new Student() { StudentID = 3, StudentName = "Bill",  Age = 18 } ,
        new Student() { StudentID = 4, StudentName = "Ram" , Age = 20} ,
        new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 } 
    };

string commaSeparatedStudentNames = studentList.Aggregate<Student, string,string>(
                                            String.Empty, // 种子值
                                            (str, s) => str += s.StudentName + ",", // 使用种子值返回结果,String.Empty以str的形式进入lambda表达式
                                            str => str.Substring(0,str.Length - 1 )); // 删除最后一个逗号的结果选择器

Console.WriteLine(commaSeparatedStudentNames);

在上面的示例中,我们指定了一个lambda表达式str => str.Substring(0,str.Length - 1 ),该表达式将删除字符串结果中的最后一个逗号。下面是VB.Net中的相同示例。

// 学生集合
Dim studentList = New List(Of Student) From {
        New Student() With {.StudentID = 1, .StudentName = "John", .Age = 13},
        New Student() With {.StudentID = 2, .StudentName = "Moin", .Age = 21},
        New Student() With {.StudentID = 3, .StudentName = "Bill", .Age = 18},
        New Student() With {.StudentID = 4, .StudentName = "Ram", .Age = 20},
        New Student() With {.StudentID = 5, .StudentName = "Ron", .Age = 15}
    }

Dim commaSeparatedStudentNames = studentList.Aggregate(Of String, String)(
               String.Empty, 
               Function(str, s) str + s.StudentName + ",", 
               Function(str) str.Substring(0, str.Length - 1)) 

Console.WriteLine(commaSeparatedStudentNames);
输出:
John, Moin, Bill, Ram, Ron

C # 或 VB.Net 中的查询语法不支持聚合运算符。

在下一部分中了解另一种合计运算符-Average (计算平均值)。