Ngôn ngữ LINQ - Toán tử Aggregate

Toán tử tổng hợp (Aggregate) trong LINQ

Các toán tử tổng hợp thực hiện các phép toán như Average, Aggregate, Count, Max, Min và Sum trên các thuộc tính của các phần tử trong danh sách.

Bảng sau liệt kê các toán tử tổng hợp có sẵn trong LINQ:

Phương thức Mô tả
Aggregate Thực hiện một thao tác tổng hợp tùy chỉnh trên các giá trị trong danh sách.
Average Tính trung bình của các phần tử kiểu số trong danh sách.
Count Đếm các yếu tố trong danh sách và trả về kiểu int.
LongCount Đếm các phần tử trong danh sách và trả về kiểu long.
Max Tìm giá trị lớn nhất trong danh sách.
Min Tìm giá trị nhỏ nhất trong danh sách.
Sum Tính tổng các giá trị trong danh sách.

Toán tử tổng hợp là một trong những toán tử truy vấn chuẩn của LINQ.


Phương thức Aggregate trong Cú pháp phương thức LINQ

Phương thức Aggregate thực hiện một thao tác tổng hợp tùy chỉnh trên các giá trị trong danh sách. Phương thức mở rộng Aggregate có các phương thức quá tải sau:


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);

Ví dụ sau đây cho thấy phương thức Aggregate sẽ tổng hợp các phần tử vào trong một chuỗi được phân tách bằng dấu phẩy từ một danh sách kiểu chuỗi.


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

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

Console.WriteLine(commaSeperatedString);

Đây là kết quả khi biên dịch và thực thi chương trình:

One, Two, Three, Four, Five

Xem ví dụ

Trong ví dụ trên, phương thức mở rộng Aggregate trả về các chuỗi gồm các phần tử được phân tách bằng dấu phẩy từ danh sách strList. Hình ảnh sau đây minh họa toàn bộ thao tác tổng hợp được thực hiện trong ví dụ trên.

Theo hình trên, phần tử đầu tiên của strList là "One" sẽ được truyền dưới dạng s1 và phần còn lại của các mục sẽ được chuyển thành s2.

Biểu thức lambda (s1, s2) => s1 + ", " + s2 sẽ được xử lý như s1 = s1 + ", " + s2 nơi s1 sẽ được tích lũy cho từng phần tử trong danh sách.

Do đó, phương thức Aggregate sẽ trả về chuỗi các phần tử được phân tách bằng dấu phẩy.

Phương thức Aggregate với giá trị Seed

Phương thức quá tải thứ hai của Aggregate yêu cầu tham số đầu tiên cho giá trị seed để tích lũy.

Tham số thứ hai là delegate kiểu Func như sau:
TAccumulate Aggregate<TSource, TAccumulate>(TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func);

Ví dụ sau sử dụng chuỗi làm giá trị seed trong phương thức mở rộng Aggregate.

// Student collection
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 result = studentList.Aggregate<Student, string>(
    "Student Names: ",  // seed value
    (str, s) => str += s.StudentName + "," ); 

Console.WriteLine(result);

Đây là kết quả khi biên dịch và thực thi chương trình:

Student Names: John,Moin,Bill,Ram,Ron,

Xem ví dụ

Trong ví dụ trên, tham số đầu tiên của phương thức Aggregate là chuỗi "Student Names:" sẽ được tích lũy với thuộc tính StudentName của các sinh viên.

Ví dụ sau sử dụng toán tử Aggregate để tính tổng tuổi của tất cả sinh viên.

// Student collection
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, (age, s) => age += s.Age); 

Console.WriteLine(sumOfStudentsAge);

Đây là kết quả khi biên dịch và thực thi chương trình:

87

Xem ví dụ

Phương thức Aggregate với bộ chọn kết quả

Bây giờ, hãy xem phương thức quá tải thứ ba yêu cầu tham số thứ ba của biểu thức delegate Func cho bộ chọn kết quả, để bạn có thể định dạng kết quả trả về.

// Student collection
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, // seed value
    (str, s) => str += s.StudentName + ",", // returns result using seed value, String.Empty goes to lambda expression as str
    str => str.Substring(0,str.Length - 1 )); // result selector that removes last comma

Console.WriteLine(commaSeparatedStudentNames);

Đây là kết quả khi biên dịch và thực thi chương trình:

John,Moin,Bill,Ram,Ron

Xem ví dụ

Trong ví dụ trên, chúng tôi đã chỉ định biểu thức lambda str => str.Substring(0,str.Length - 1 ) sẽ xóa dấu phẩy cuối cùng trong chuỗi kết quả.

Lưu ý: Toán tử Aggregate không hỗ trợ cú pháp truy vấn LINQ.