Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I sum a list<> of arrays

Tags:

c#

linq

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?

like image 324
Will Dean Avatar asked Nov 22 '08 20:11

Will Dean


People also ask

How do you sum an array list in Python?

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.

How do I sum a list in NumPy?

sum() in Python. numpy. sum(arr, axis, dtype, out) : This function returns the sum of array elements over the specified axis.


2 Answers

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.

like image 191
Mark Brackett Avatar answered Oct 16 '22 04:10

Mark Brackett


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.

like image 21
Jon Skeet Avatar answered Oct 16 '22 06:10

Jon Skeet