Reputation: 33880
Is there a standard linq operator that will help me generate, say, an arithmetic progression out of an IEnumerable<int>
without actually iterating over the elements myself?
For e.g.
int[] numbers = { 7, 12, 14, 8 };
// I would like an IEnumerable<int>
// whose values are:
IEnumerable<int> result = ... // { 19, 33, 41 }
I want to do this in a single query lazily, i.e. without having to write a foreach
loop.
I am looking but can't find any combinator out of the standard ones.
I suspect I can use one of the overloads of Select
coupled with Aggregate
might help me do that but I am still trying it out myself and am not sure. I thought it'll be interesting to post this question and have someone else race me to it?
Update I have changed my question. The output I thought I wanted was:
{ 7 ,19, 33, 41}
Jacob answered it correctly with the code:
var accumulator = 0;
return numbers.Select(n => accumulator += n);
But I am thinking, if I wanted the output to be just
{ 19, 33, 41 }
How would I "look ahead" into the same source enumerable?
Upvotes: 0
Views: 249
Reputation: 144206
This operation is usually called scan. There's no built-in operator (although F# defines it as Seq.scan
but you can define it yourself:
public static IEnumerable<TAcc> Scan<T, TAcc>(this IEnumerable<T> seq, Func<TAcc, T, TAcc> f, TAcc initial)
{
TAcc current = initial;
yield return current;
foreach(T item in seq)
{
current = f(current, item);
yield return current;
}
}
Scan usually yields the initial value which you don't need so you can Skip
it:
int[] numbers = { 7, 12, 14, 8 };
var result = numbers.Scan((acc, x) => acc + y, 0).Skip(1);
Upvotes: 2
Reputation: 78890
I don't know of any built-in operator to do exactly this, but it's fairly easy to implement just through a regular Select
:
var accumulator = 0;
return numbers.Select(n => accumulator += n);
Upvotes: 2