I have a following code that transforms each element of an array into sum of all elements before it. The procedural implementation is as follows:
float[] items = {1, 5, 10, 100}; //for example
float[] sums = new float[items.Length];
float total = 0;
for(int i = 0; i < items.Length; i++){
total+=items[i];
sums[i] = total;
}
How would I implement this as a LINQ one-liner?
I know it can be done for example as
items.Select((x, i) => items.Take(i + 1).Sum())
but I think it’s not very efficient when the array size grows, as it has to do Sum() for each element.
LINQ doesn’t support this case very cleanly, to be honest – you want a mixture of aggregation and projection. You can do it with side-effects, which is horrible:
Side-effects in LINQ are nasty. Likewise you can do it using
Take/Sumas shown by RePierre and L.B – but that takes an operation which is naturally O(N) and converts it into an operation which is O(N^2).The MoreLINQ project I started a while ago does have support for this, in its
ScanandPreScanmembers. In this case you wantScan, I believe:If you don’t want to use a third-party library, don’t want to use side-effects, don’t want the inefficiency of the
Takesolution, and only need addition, and only need it for a single type (e.g.floatin your case) you can easily introduce your own method:As you’ll have noticed, this is basically the same code as your original – but is lazily evaluated and applies to any sequence of floats.