I have a sequence of numbers:
var seq = new List<int> { 1, 3, 12, 19, 33 };
and I want to transform that into a new sequence where the number is added to the preceding numbers to create a new sequence:
{ 1, 3, 12, 19, 33 } --> {1, 4, 16, 35, 68 }
I came up with the following, but I dislike the state variable 'count'. I also dislike the fact that I'm using the values Enumerable without acting on it.
int count = 1;
var summed = values.Select(_ => values.Take(count++).Sum());
How else could it be done?
This is a common pattern in functional programming which in F# is called scan. It's like C#'s Enumerable.Aggregate and F#'s fold except that it yields the intermediate results of the accumulator along with the final result. We can implement scan in C# nicely with an extension method:
public static IEnumerable<U> Scan<T, U>(this IEnumerable<T> input, Func<U, T, U> next, U state) {
yield return state;
foreach(var item in input) {
state = next(state, item);
yield return state;
}
}
And then use it as follows:
var seq = new List<int> { 1, 3, 12, 19, 33 };
var transformed = seq.Scan(((state, item) => state + item), 0).Skip(1);
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