FinQ Reduce
The Reduce function uses an initial value and an aggregation function to build a result value from a sequence. Taking the sum of a set of numbers is a reduction, a reduction by addition.
public static R Reduce<T, R>(this IEnumerable<t> list, R init, Agg<T, R> agg)
{
R result = init;
if( null == list ) return result;
foreach (T it in list)
result = agg(it, result);
return result;
}
The Reduce implementation above is very similar to Map in that it takes two template types T and R for the input type and result type. Reduce adds an init parameter matching the result type which is used to seed the reduction. For sum or count functions, zero would likely be a good init value. If you had a long-running calculation that needed to be suspended and resumed a non-zero init value might be useful. I’ll re-visit the Reduce implemenation soon and use some non-scalar types for the result and init types.
The Agg<T,R> type is a delegate(function signature) that accepts an object of type T and an object of type R but returns a single object of type R. During the execution of the Reduce function, each result is folded into the next aggregate function call. (For the first call, init is folded into the call.)
The SQL aggregation functions MIN, MAX, AVG, COUNT, and SUM have simple corresponding Reduce functions. Before I demonstrate how those work, let’s take a look at the C# lambda function.