In my code base, I have a large number of classes that must perform various collective operations on their members to get results (average, standard deviation, confidence intervals, etc.).
The AverageLINQ Extension extension method already exists, but StandardDeviationdoes not work, so I implemented it as follows:
public static double StandardDeviation<T>(this IEnumerable<T> source, Func<T, double> selector)
{
var average = source.Average(selector);
var sumOfSquares = source.Sum(sample => Math.Pow(selector(sample) - average, 2));
return Math.Pow(sumOfSquares, 0.5);
}
I would like to find a way to define a delegate for this function, ideally as a LINQ extension, to avoid code duplication. The following is an example of the current use of two methods:
public override void Average(IList<ThisType> samples)
{
TotalEntered = samples.Average(sample => sample.TotalEntered);
TotalExited = samples.Average(sample => sample.TotalExited);
MinimumContents = samples.Average(sample => sample.MinimumContents);
AverageContents = samples.Average(sample => sample.AverageContents);
MaximumContents = samples.Average(sample => sample.MaximumContents);
MinimumTime = samples.Average(sample => sample.MinimumTime);
AverageTime = samples.Average(sample => sample.AverageTime);
MaximumTime = samples.Average(sample => sample.MaximumTime);
StdDevTime = samples.Average(sample => sample.StdDevTime);
AverageNonZeroTime = samples.Average(sample => sample.AverageNonZeroTime);
PercentageWithinLimit = samples.Average(sample => sample.PercentageWithinLimit);
base.Average(samples);
}
public override void StandardDeviation(IList<ThisType> samples)
{
TotalEntered = samples.StandardDeviation(sample => sample.TotalEntered);
TotalExited = samples.StandardDeviation(sample => sample.TotalExited);
MinimumContents = samples.StandardDeviation(sample => sample.MinimumContents);
AverageContents = samples.StandardDeviation(sample => sample.AverageContents);
MaximumContents = samples.StandardDeviation(sample => sample.MaximumContents);
MinimumTime = samples.StandardDeviation(sample => sample.MinimumTime);
AverageTime = samples.StandardDeviation(sample => sample.AverageTime);
MaximumTime = samples.StandardDeviation(sample => sample.MaximumTime);
StdDevTime = samples.StandardDeviation(sample => sample.StdDevTime);
AverageNonZeroTime = samples.StandardDeviation(sample => sample.AverageNonZeroTime);
PercentageWithinLimit = queueSamples.StandardDeviation(sample => sample.PercentageWithinLimit);
base.StandardDeviation(samples);
}
I tried to create a delegate for these methods as follows:
public delegate double CollectiveOperation<T>(IEnumerable<T> source, Func<T, double> selector);
Used in the following replacement of the above code duplication:
public void Operation(IList<ThisType> samples, LINQExtensions.CollectiveOperation<ThisType> Operation)
{
BufferMinimumTime = samples.Operation(sample => sample.BufferMinimumTime);
BufferAverageTime = samples.Operation(sample => sample.BufferAverageTime);
BufferMaximumTime = samples.Operation(sample => sample.BufferMaximumTime);
BufferStdDevTime = samples.Operation(sample => sample.BufferStdDevTime);
TotalMinimumTime = samples.Operation(sample => sample.TotalMinimumTime);
TotalAverageTime = samples.Operation(sample => sample.TotalAverageTime);
TotalMaximumTime = samples.Operation(sample => sample.TotalMaximumTime);
TotalStdDevTime = samples.Operation(sample => sample.TotalStdDevTime);
base.Operation(samples);
}
Average StandardDeviation , - this. StandardDeviation - :
BufferMinimumTime = Operation(samples, sample => sample.BufferMinimumTime);
- , :
Expected a method with 'double StandardDeviation(IEnumerable<ThisType>, Func<ThisType, double>)' signature.
LINQ, ? , .