When we deal with a factorial formula, we can use LINQ Aggregate to refactor our recursive function into a functional approach. LINQ Aggregate will accumulate the given sequence, and then we will have the result of the recursion from the accumulator. In Chapter 1, Tasting Functional Style in C# we have already done this refactoring. Let's borrow the code from the chapter to analyze the use of the Aggregate
method. The following code will use the Aggregate
method, which we can find in the RecursionUsingAggregate.csproj
project:
public partial class Program { private static void GetFactorialAggregate(int intNumber) { IEnumerable<int> ints = Enumerable.Range(1, intNumber); int factorialNumber = ints.Aggregate((f, s) => f * s); Console.WriteLine("{0}! (using Aggregate) is {1}", intNumber, factorialNumber); } }
If we run the preceding GetFactorialAggregate()
method and pass 5
as the parameter, we will get the following output on the console:
As we can see in the preceding console screenshot, we get the exact same result compared to what we get with the use of nonaggregate recursion.
As we discussed earlier, the Aggregate
method will accumulate the given sequence. Let's take a look at the following code, which we can find in the AggregateExample.csproj
project file, to demonstrate how the Aggregate
method works:
public partial class Program { private static void AggregateInt() { List<int> listInt = new List<int>() { 1, 2, 3, 4, 5, 6 }; int addition = listInt.Aggregate( (sum, i) => sum + i); Console.WriteLine("The sum of listInt is " + addition); } }
From the preceding code, we can see that we have a list of int
data types, which contains numbers from 1 to 6. We then invoke the Aggregate
method to sum up the members of listInt
. Here is the flow of the preceding code:
(sum, i) => sum + i sum = 1 sum = 1 + 2 sum = 3 + 3 sum = 6 + 4 sum = 10 + 5 sum = 15 + 6 sum = 21 addition = sum
If we run the preceding AggregateInt()
method, we will get the following output on the console:
Actually, the Aggregate
method not only adds the number, but it also adds the string. Let's examine the following code, which demonstrates the Aggregate
method used to add the string sequence:
public partial class Program { private static void AggregateString() { List<string> listString = new List<string>() {"The", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"}; string stringAggregate = listString.Aggregate((strAll, str) => strAll + " " + str); Console.WriteLine(stringAggregate); } }
If we run the preceding AggregateString()
method, we will get the following output on the console:
The following is a declaration of the Aggregate
method that we can find in MSDN:
public static TSource Aggregate<TSource>( this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func )
The following is the flow of the AggregateUsage()
method based on the previous declaration:
(strAll, str) => strAll + " " + str strAll = "The" strAll = strAll + " " + str strAll = "The" + " " + "quick" strAll = "The quick" + " " + "brown" strAll = "The quick brown" + " " + "fox" strAll = "The quick brown fox" + " " + "jumps" strAll = "The quick brown fox jumps" + " " + "over" strAll = "The quick brown fox jumps over" + " " + "the" strAll = "The quick brown fox jumps over the" + " " + "lazy" strAll = "The quick brown fox jumps over the lazy" + " " + "dog" strAll = "The quick brown fox jumps over the lazy dog" stringAggregate = str
From the preceding flow, we can concatenate all strings in listString
using the Aggregate
method. This proves that not only can the int
data type be handled, but the string data type can be handled as well.