I have a List< int[] > myList, where I know that all the int[] arrays are the same length - for the sake of argument, let us say I have 500 arrays, each is 2048 elements long. I'd like to sum all 500 of these arrays, to give me a single array, 2048 elements long, where each element is the sum of all the same positions in all the other arrays.
Obviously this is trivial in imperative code:
int[] sums = new int[myList[0].Length];
foreach(int[] array in myList)
{
for(int i = 0; i < sums.Length; i++)
{
sums[i] += array[i];
}
}
But I was wondering if there was a nice Linq or Enumerable.xxx technique?
Python provides an inbuilt function sum() which sums up the numbers in the list. Syntax: sum(iterable, start) iterable : iterable can be anything list , tuples or dictionaries , but most importantly it should be numbers.
sum() in Python. numpy. sum(arr, axis, dtype, out) : This function returns the sum of array elements over the specified axis.
Edit: Ouch...This became a bit harder while I wasn't looking. Changing requirements can be a real PITA.
Okay, so take each position in the array, and sum it:
var sums = Enumerable.Range(0, myList[0].Length)
.Select(i => myList.Select(
nums => nums[i]
).Sum()
);
That's kind of ugly...but I think the statement version would be even worse.
EDIT: I've left this here for the sake of interest, but the accepted answer is much nicer.
EDIT: Okay, my previous attempt (see edit history) was basically completely wrong...
You can do this with a single line of LINQ, but it's horrible:
var results = myList.SelectMany(array => array.Select(
(value, index) => new { value, index })
.Aggregate(new int[myList[0].Length],
(result, item) => { result[item.index] += value; return result; });
I haven't tested it, but I think it should work. I wouldn't recommend it though. The SelectMany flattens all the data into a sequence of pairs - each pair is the value, and its index within its original array.
The Aggregate step is entirely non-pure - it modifies its accumulator as it goes, by adding the right value at the right point.
Unless anyone can think of a way of basically pivoting your original data (at which point my earlier answer is what you want) I suspect you're best off doing this the non-LINQ way.
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