LINQ Farm Seed I: Aggregate Operator Part I

LINQ Farm Seeds are short posts designed to be read in a few minutes. The first seed showed how to list in alphabetical order all the operators used in LINQ to Objects. At the top of the list one found the Aggregate operator.

The LINQ Aggregation operator is easy to use. Consider the following declaration:

 List<int> ints = new List<int> { 1, 2, 3 };

The aggregate of the numbers in this list would be 1 + 2 + 3 or 6. Consider this array:

List<int> ints = new List<int> { 1, 2, 3, 4 };

The aggregate of the numbers in this list would be 10:

10 = 1 + 2 + 3 + 4;

To perform this kind of calculation one could take the first two numbers in the list, add them together to get 3, then add the third number to their sum to get 6, then add the fourth number that sum to get 10:

  • 3 = 1 + 2
  • 6 = 3 + 3
  • 10 = 6 + 4

This algorithm is used by the first of the three overrides of the LINQ to Objects Aggregate operator. Using typical LINQ syntax, one could call the operator as follows:

 int sum = integers.Aggregate((a, b) => a + b);

The Aggregate operator is passed a simple lambda expression that takes two parameters and adds them together. In our case, using the List<int> shown above, the first two parameters would be 1 and 2 and the return value would be 3. The function derived from the lambda expression would then be called again with the value 3 and 3, and so on.

If you are not yet quite comfortable using lambdas, you could accomplish the same ends with the following code:

 private int AddEm(int a, int b)
{
   return a + b;
}

 int sum = integers.Aggregate(AddEm);

This code also compiles and runs correctly. It is semantically equivalent to the lambda expression code shown above it. The word lambda sounds complicated, but in some ways lambda expressions are even easier to create and understand than a method such as AddEm().

A complete program implementing the Aggregate operator is shown in Listing 1.

Listing 1: A short LINQ program that outputs the number 10.

 using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int count = 5;
            
            List<int> integers = new List<int>();
            for (int i = 0; i < count; i++)
            {            
              integers.Add(i);
            }
            
            int sum = integers.Aggregate((a, b) => a + b);

            Console.WriteLine(sum);

        }
    }
}

It would be a bit more fun to use this program if would could dynamically change the value of count. To make this possible I have created a simple Windows Form application. You can download this implementation from the LINQ Farm on Code Gallery. A screen shot from the application is shown in Figure 1.

Seed01Aggregate

Figure 01: The aggregate of 0 + 1 + 2 + 3 + 4 is 10.

Here is the declaration for this first override of the Aggregate operator:

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

Since it is an extension method, the first parameter to this generic method is effectively ignored. As a result, we need only be concerned with the second parameter, which looks like this:

Func<TSource, TSource, TSource> func

Assuming we are passing in an array of integers to this LINQ operator, then this declaration states that Func takes two integers as parameters and returns an integer:

int Func(int a, int b)

If you look up above at the AddEm method, you will see that it has the same signature. The lambda expression we have been using also generates code with the same signature:

(a, b) => a + b;

In this short post you have seen how to work with the first override of the Aggregate operator. In future posts, I will show how to work with other overrides of this same operator.

---

Down the source code from the LINQ Farm.

I want to get my hands dirty; show me more LINQ Farm posts.