0

I have these arrays:

// I want to calculate these arrays each other.
var a = [1,2,3]
var b = [1,2,3]
var c = [3,4,5]
// ->
var result = [5, 8, 11]

I can calculate two array with below method but how can I sum n arrays?

Array.prototype.Sum = function (arr) {
    var s = [];
    if (arr != null && this.length == arr.length) {
        for (var i = 0; i < arr.length; i++) {
            var c = this[i] + arr[i]
            s.push(c);
        }
    }
    return s;
}
4
  • 2
    a.sum(b).sum(c)? Note lower case s, Sum is not a constructor. ;-) Commented Dec 18, 2014 at 0:49
  • You want something like zipWith. Commented Dec 18, 2014 at 0:49
  • @RobG I have about 5k arrays like that. Commented Dec 18, 2014 at 0:55
  • @Lazy—if you have that many, you should find the looping answers much faster than those using built–in methods, see http://jsperf.com/summing-arrays-again where loops are 10 times faster than built–ins. Don't judge a solution by the lines of code. ;-) Commented Dec 18, 2014 at 3:38

4 Answers 4

5

Assuming

var arrays = [
    [1,2,3],
    [1,2,3],
    [3,4,5]
];

Using your Sum with EcmaScript 5 array methods,

var result = arrays.reduce(function(arr1, arr2){
    return arr1.Sum(arr2);
});

Alternatively, consider not polluting Array.prototype and just using something like (ES5)

var result = arrays.reduce(function(arr1, arr2) {
    return arr1.map(function(num, index){
        return num+arr2[index];
    });
});

Or, simplifying using EcmaScript 6 arrow functions,

var result = arrays.reduce(
    (arr1, arr2) => arr1.map(
        (num, index) => num+arr2[index]
    )
);
Sign up to request clarification or add additional context in comments.

5 Comments

This is not it, result gives [6,6,12] when it should be [5,8,11]
@elclanrs True, fixed.
Be aware that the reduce and map functions are parts of the ECMAScript 5 specification, which is only supported by modern browsers. If that's an issue for you, you will have to use a polyfill, which adds the functionality to older browsers.
Note that for loops are nearly always faster than methods like map and reduce. Slightly more code, but faster.
Oh, and if the built–ins have been pollyfilled, they will be very, very much slower than plain loops.
3

A plain old ECMAScript 3 solution:

var arrays = [
    [1, 2, 3],
    [1, 2, 3],
    [3, 4, 5]
];

function sum() {
  var sum = [];
  for(var i = 0; i < arguments.length; ++i) {
    for(var j = 0; j < arguments[i].length; ++j)
      sum[j] = (sum[j] || 0) + arguments[i][j];
  } return sum;
}

sum.apply(this, arrays);              // [ 5, 8, 11 ]
sum(arrays[0], arrays[1], arrays[2]); // [ 5, 8, 11 ]

2 Comments

Loops are fast, you might find sum.push(...) faster than sum[j] = ....
That wouldn't preserve the semantics, though. I'm accessing each sum[j] arguments.length times (given the input arrays have the same length).
3

With this function, you can sum several arrays and you don't need to "encapsulate" your arrays into another array...

Also, it works on old browsers.

function Sum(){
  if (arguments.length == 0){
    return null;
  }
  var s = arguments[0];
  for(var j = 1; j < arguments.length; j++) {
     var arr = arguments[j];
     for (var i = 0; i < arr.length; i++) {
         s[i] = s[i] + arr[i];
     }
  }
  return s;
}

Just call Sum(a, b) or Sum(a, b, c) ...

You can put it in your prototype too if you want (and make little changes to use this if you want to sum in place).

1 Comment

The first if block is redundant. If no arguments are provided, s will be undefined, the outer for loop will not run so undefined will be returned. Or you could do return s || null;, but undefined makes more sense to me. ;-)
-1
a.sum(b).sum(c);

That should do it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.