Aggregate Operators

Count - Simple

This sample uses Count to get the number of unique prime factors of 300.

Code:

            public void Linq73()
            {
                int[] primeFactorsOf300 = { 2, 2, 3, 5, 5 };

                int uniqueFactors = primeFactorsOf300.Distinct().Count();

                Log.WriteLine("There are {0} unique prime factors of 300.", uniqueFactors);
            }

Result:

Count - Conditional

This sample uses Count to get the number of odd ints in the array.

Code:

            public void Linq74()
            {
                int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

                int oddNumbers = numbers.Count(n => n % 2 == 1);

                Log.WriteLine("There are {0} odd numbers in the list.", oddNumbers);
            }

Result:

Count - Nested

This sample uses Count to return a list of customers and how many orders each has.

Code:

            public void Linq76()
            {
                List customers = GetCustomerList();

                var orderCounts = customers.Select(cust => new {cust.CustomerID, OrderCount = cust.Orders.Count()});

                ObjectDumper.Write(orderCounts);
            }

Result:

Count - Grouped

This sample uses Count to return a list of categories and how many products each has.

Code:

            public void Linq77()
            {
                List products = GetProductList();

                var categoryCounts = products.GroupBy(prod => prod.Category).
                    Select(prodGroup => new {Category = prodGroup.Key, ProductCount = prodGroup.Count()});

                ObjectDumper.Write(categoryCounts);
            }

Result:

Sum - Simple

This sample uses Sum to add all the numbers in an array.

Code:

            public void Linq78()
            {
                int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

                double numSum = numbers.Sum();

                Log.WriteLine("The sum of the numbers is {0}.", numSum);
            }

Result:

Sum - Projection

This sample uses Sum to get the total number of characters of all words in the array.

Code:

            public void Linq79()
            {
                string[] words = { "cherry", "apple", "blueberry" };

                double totalChars = words.Sum(w => w.Length);

                Log.WriteLine("There are a total of {0} characters in these words.", totalChars);
            }

Result:

Sum - Grouped

This sample uses Sum to get the total units in stock for each product category.

Code:

            public void Linq80()
            {
                List products = GetProductList();

                var categories = products.GroupBy(prod => prod.Category).
                    Select(prodGroup => new {Category = prodGroup.Key, TotalUnitsInStock = prodGroup.Sum(p => p.UnitsInStock)});

                ObjectDumper.Write(categories);
            }

Result:

Min - Simple

This sample uses Min to get the lowest number in an array.

Code:

            public void Linq81()
            {
                int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

                int minNum = numbers.Min();

                Log.WriteLine("The minimum number is {0}.", minNum);
            }

Result:

Min - Projection

This sample uses Min to get the length of the shortest word in an array.

Code:

            public void Linq82()
            {
                string[] words = { "cherry", "apple", "blueberry" };

                int shortestWord = words.Min(w => w.Length);

                Log.WriteLine("The shortest word is {0} characters long.", shortestWord);
            }

Result:

Min - Grouped

This sample uses Min to get the cheapest price among each category's products.

Code:

            public void Linq83()
            {
                List products = GetProductList();

                var categories = products.GroupBy(prod => prod.Category).Select(prodGroup => new {Category = prodGroup.Key, CheapestPrice = prodGroup.Min(p => p.UnitPrice)});

                ObjectDumper.Write(categories);
            }

Result:

Min - Elements

This sample uses Min to get the products with the lowest price in each category.

Code:

            public void Linq84()
            {
                List products = GetProductList();

                var categories = products.GroupBy(prod => prod.Category).
                    Select(prodGroup => new {prodGroup, minPrice = prodGroup.Min(p => p.UnitPrice)}).
                    Select(@t => new {
                        Category = @t.prodGroup.Key, 
                        CheapestProducts = @t.prodGroup.Where(p => p.UnitPrice == @t.minPrice)});

                ObjectDumper.Write(categories, 1);
            }

Result:

Max - Simple

This sample uses Max to get the highest number in an array. Note that the method returns a single value.

Code:

            public void Linq85()
            {
                int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

                int maxNum = numbers.Max();

                Log.WriteLine("The maximum number is {0}.", maxNum);
            }

Result:

Max - Projection

This sample uses Max to get the length of the longest word in an array.

Code:

            public void Linq86()
            {
                string[] words = { "cherry", "apple", "blueberry" };

                int longestLength = words.Max(w => w.Length);

                Log.WriteLine("The longest word is {0} characters long.", longestLength);
            }

Result:

Max - Grouped

This sample uses Max to get the most expensive price among each category's products.

Code:

            public void Linq87()
            {
                List products = GetProductList();

                var categories = products.GroupBy(prod => prod.Category)
                    .Select(prodGroup => new {Category = prodGroup.Key, MostExpensivePrice = prodGroup.Max(p => p.UnitPrice)});

                ObjectDumper.Write(categories);
            }

Result:

Max - Elements

This sample uses Max to get the products with the most expensive price in each category.

Code:

            public void Linq88()
            {
                List products = GetProductList();

                var categories = products.GroupBy(prod => prod.Category)
                    .Select(prodGroup => new {
                        prodGroup, 
                        maxPrice = prodGroup.Max(p => p.UnitPrice)}).Select(@t => new {
                            Category = @t.prodGroup.Key, 
                            MostExpensiveProducts = @t.prodGroup.Where(p => p.UnitPrice == @t.maxPrice)});

                ObjectDumper.Write(categories, 1);
            }

Result:

Average - Simple

This sample uses Average to get the average of all numbers in an array.

Code:

            public void Linq89()
            {
                int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

                double averageNum = numbers.Average();

                Log.WriteLine("The average number is {0}.", averageNum);
            }

Result:

Average - Projection

This sample uses Average to get the average length of the words in the array.

Code:

            public void Linq90()
            {
                string[] words = { "cherry", "apple", "blueberry" };

                double averageLength = words.Average(w => w.Length);

                Log.WriteLine("The average word length is {0} characters.", averageLength);
            }

Result:

Average - Grouped

This sample uses Average to get the average price of each category's products.

Code:

            public void Linq91()
            {
                List products = GetProductList();

                var categories = products.GroupBy(prod => prod.Category).
                    Select(prodGroup => new {Category = prodGroup.Key, AveragePrice = prodGroup.Average(p => p.UnitPrice)});

                ObjectDumper.Write(categories);
            }

Result:

Aggregate - Simple

This sample uses Aggregate to create a running product on the array that calculates the total product of all elements.

Code:

            public void Linq92()
            {
                double[] doubles = { 1.7, 2.3, 1.9, 4.1, 2.9 };

                double product = doubles.Aggregate((runningProduct, nextFactor) => runningProduct * nextFactor);

                Log.WriteLine("Total product of all numbers: {0}", product);
            }

Result:

Aggregate - Seed

This sample uses Aggregate to create a running account balance that subtracts each withdrawal from the initial balance of 100, as long as the balance never drops below 0.

Code:

            public void Linq93()
            {
                double startBalance = 100.0;

                int[] attemptedWithdrawals = { 20, 10, 40, 50, 10, 70, 30 };

                double endBalance =
                    attemptedWithdrawals.Aggregate(startBalance,
                        (balance, nextWithdrawal) =>
                            ((nextWithdrawal <= balance) ? (balance - nextWithdrawal) : balance));

                Log.WriteLine("Ending balance: {0}", endBalance);
            }

Result: