Introduction
In this article, we are going to look into the C# feature called Accumulator functions. In general, accumulate means reduce; these functions are so-called since they will accumulate/reduce a data structure in some order and build up a return value.
These functions accept three things.
- A combining function.
- A Data structure has a list of elements.
- A seed/initial value.
It proceeds to combine elements of the list using the function in a systematic way.
Let's see this as an example. Create a new VS 2008 Console application with the name AccumulatorMethodSample. Now, add the code below to the Program. cs.
class Program
{
static void Main(string[] args)
{
int[] myNumbers = { 10, 20, 30, 40 };
int mySum = myNumbers.Aggregate(1, (s, n) => s + n);
int myProduct = myNumbers.Aggregate((s, n) => s * n);
int myDifference = myNumbers.Aggregate((s, n) => s - n);
Console.WriteLine("Sum is: " + mySum.ToString());
Console.WriteLine("Difference is: " + myDifference.ToString());
Console.WriteLine("Product is: " + myProduct.ToString());
Console.ReadLine();
}
}
In the above code, the Aggregate accumulator is accepting the seed value as 1 and a lambda expression saying to add the values. This function gets a value by accumulating the numbers list without modifying it.
For all the accumulators, there is a default seed value based on the operation being performed.
Operation |
Default Seed |
+ |
0 |
- |
0 |
* |
1 |
/ |
1 |
Output
Now, let's see the accumulator's internal calculation for the above operations.
For + [addition], the value will be calculated in the below way.
((1 + 10) + 20 ) + 30 ) + 40 ) = 101
For -, the value will be calculated in the below way.
(((10 – 20) – 30) – 40) = -80
In this way, it works by taking the accumulator and the first element in the list and applying the lambda expression to them. The result becomes a new accumulator. Then, the expression is applied to the new accumulator and the second element of the list. This process is repeated with all the elements of the list. Built-in accumulator functions are available over all the collections as an Extension method present in the System. Linq namespace. Now, we will move over to creating our own accumulator.
Example
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main(string[] args)
{
int[] myNumbers = { 10, 20, 30, 40 };
int mySum = myNumbers.Aggregate(1, (s, n) => s + n);
int myProduct = myNumbers.Aggregate((s, n) => s * n);
int myDifference = myNumbers.Aggregate(1, (s, n) => s - n);
int myLeastNbr = Accumulator((s, n) => (s >= n) ? n : s, Int32.MaxValue, myNumbers);
Console.WriteLine("Sum is: " + mySum.ToString());
Console.WriteLine("Difference is: " + myDifference.ToString());
Console.WriteLine("Product is: " + myProduct.ToString());
Console.WriteLine("Least Number is: " + myLeastNbr.ToString());
Console.ReadLine();
}
public delegate T Func<T>(T val1, T val2);
public static T Accumulator<T>(Func<T> function, T accumulator, IEnumerable<T> list)
{
foreach (T listItem in list)
accumulator = function(listItem, accumulator);
return accumulator;
}
}
Here, we are defining a delegate, which will act as a placeholder for the function's behavior as a first argument in the Accumulator function. Finally, we are defining our own Accumulator with a recursive call to the lambda expression with a new accumulator's value in the for loop. Once the elements in the list are completed, we will return the final result.
Output
In this way, we can write our own accumulator functions. These functions are also called Fold functions.
I am ending things here. I am attaching the source code for reference. I hope this article will be helpful for all.