BlackWaspTM
LINQ
.NET 3.5+

LINQ Aggregation (2)

The seventh part of the LINQ to Objects tutorial looks at aggregate functions. These are standard query operators that can be applied to sequences and groups, performing a calculation that combines all of the values in a collection.

LongCount

The LongCount operator is almost identical to Count. It can be used for entire sequences or for groups, and can include a predicate that determines which items to count. The key difference is that the result is a long, rather than a standard integer.

var groupCounts = stock.GroupBy(s => s.Category,
    (c, i) => new { Category = c, Count = i.LongCount(s => s.Price > 0.3) });

/* RESULTS

{ Category = Fruit, Count = 1 }
{ Category = Vegetable, Count = 1 }
{ Category = Dairy, Count = 1 }

*/

Sum

The Sum method totals the values in a sequence. When used with a collection that contains only numeric values, the method can be used with no arguments. In the sample below, the values in an array of integers are summed:

var sum = new int[] { 1, 2, 3, 4 }.Sum(); // sum = 10

If you are working with non-numeric types, an overloaded version of Sum can be used. This overload accepts a single parameter containing a Func delegate that returns the values to sum, known as a selector function. This is demonstrated in the example below, which groups the stock items by category and sums the prices in each group. The lambda expression, "s => s.Price" is used to return each price.

var groupSums = stock.GroupBy(s => s.Category,
    (c, i) => new { Category = c, Sum = i.Sum(s => s.Price) });

/* RESULTS

{ Category = Fruit, Sum = 0.94 }
{ Category = Vegetable, Sum = 1.08 }
{ Category = Dairy, Sum = 1.12 }

*/

NB: if the sequence of values contains no items, the sum will be zero.

Max and Min

The Max and Min standard query operators return the largest and smallest values in a sequence respectively. As with Sum, these operators can be used without parameters for numeric sequences or with a Func delegate parameter that returns the values to be compared.

var groupMaxMin = stock.GroupBy(s => s.Category, (c, i) => new
    {
        Category = c,
        Max = i.Max(s => s.Price),
        Min = i.Min(s => s.Price)
    });

/* RESULTS

{ Category = Fruit, Max = 0.35, Min = 0.29 }
{ Category = Vegetable, Max = 0.49, Min = 0.29 }
{ Category = Dairy, Max = 1.12, Min = 1.12 }

*/
12 August 2010