Given an array of positive and negative numbers is there a Linq expression that can get intermediate values?
for example
var heights = new List<int>();
var numbers = new [] { 5, 15, -5, -15 };
var curHeight = 0;
foreach (var number in numbers)
{
curHeight = curHeight + number;
heights.add(curHeight);
}
This function will return [5, 20, 15, 0]
Aggregate can be used the same way and it would go through this sequence
numbers.aggregate((a, b) => a + b);
0 + 5 = 5, 5 + 15 = 20, 20 - 5 = 15, 15 - 15 = 0
My question is, is there a way to use aggregate or some other so that the intermediate values [5, 20, 15, 0]
are returned?
What you need is a custom version of aggregate:
public static IEnumerable<R> AggregateSequence<A, R>(
this IEnumerable<A> items,
Func<A, R, R> aggregator,
R initial)
{
// Error cases go here.
R result = initial;
foreach(A item in items)
{
result = aggregator(item, result);
yield return result;
}
}
That is a general mechanism for solving your specific problem:
public static IEnumerable<int> MovingSum(this IEnumerable<int> items)
{
return items.AggregateSequence( (item, sum) => item + sum, 0 );
}
And now you can solve your problem with
mySequence.MovingSum().Max();
With usage of Aggregate
:
var result = numbers.Aggregate(new List<int>(), (a,b)=>
{
a.Add(a.LastOrDefault()+b);
return a;
});
result wil be:
[5,20,15,0]
If you want to have a Max value, you could use custom Result class:
public class Result
{
public List<int> Values {get;set;}
public int Max => Values.Max();
public Result()
{
Values = new List<int>();
}
}
use it:
var result = numbers.Aggregate(new Result(), (a,b)=>
{
a.Values.Add(a.Values.LastOrDefault()+b);
return a;
});
and you will get the same List as result.Values
and [20] as result.Max
You can do this stuff within your aggregate function:
var intermidiateValues = new List<int>();
numbers.aggregate((intermidiateValue, next) => {
intermidiateValues.Add(intermidiateValue);
return intermidiateValue + next;
});
And then use
intermidiateValues.Max();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With