64

I want to sum each value of an array of numbers with its corresponding value in a different array of numbers, and I want to do this without looping through each individual value.

So:

var array1 = [1,2,3,4];
var array2 = [5,6,7,8];

var sum    = [6,8,10,12];

I'd love to do it in one fell swoop, instead of doing this:

for(var i = 0; i < array1.length; i++){
   sum.push(array1[i] + array2[i]);
}

Can anyone think of a way? I'm pretty stumped.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
TheNovice
  • 1,277
  • 3
  • 16
  • 23
  • 1
    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map ... you have to iterate one way or another. – Felix Kling Jun 07 '14 at 06:35
  • There are no array math operations built into the language that will do this for you. Write yourself a little function to do it and just call that function whenever you need it. – jfriend00 Jun 07 '14 at 06:36
  • 1
    @jfriend00 - this is the only time I've wished any other language were R. – TheNovice Jun 07 '14 at 06:43
  • Probably one of these answers help to achieve what you want: http://stackoverflow.com/questions/4856717/javascript-equivalent-of-pythons-zip-function – Gábor Bakos Jun 07 '14 at 06:55

17 Answers17

106

I know this is an old question but I was just discussing this with someone and we came up with another solution. You still need a loop but you can accomplish this with the Array.prototype.map().

var array1 = [1,2,3,4];
var array2 = [5,6,7,8];

var sum = array1.map(function (num, idx) {
  return num + array2[idx];
}); // [6,8,10,12]
twalters
  • 1,204
  • 2
  • 12
  • 12
31

Here is a generic solution for N arrays of possibly different lengths.

It uses Array.prototype.reduce(), Array.prototype.map(), Math.max() and Array.from():

function sumArrays(...arrays) {
  const n = arrays.reduce((max, xs) => Math.max(max, xs.length), 0);
  const result = Array.from({ length: n });
  return result.map((_, i) => arrays.map(xs => xs[i] || 0).reduce((sum, x) => sum + x, 0));
}

console.log(...sumArrays([0, 1, 2], [1, 2, 3, 4], [1, 2])); // 2 5 5 4
jo_va
  • 13,504
  • 3
  • 23
  • 47
  • To pass an array of arrays into sumArrays function, this is how I called this `var arr = [[1,2,3,4],[1,2,3,4]]; console.log(...sumArrays(...arr)); // 2 4 6 8` – Vikas Khunteta May 18 '23 at 11:21
25
var arr = [1,2,3,4];
var arr2 = [1,1,1,2];

var squares = arr.map((a, i) => a + arr2[i]);

console.log(squares);
Dang Cong Duong
  • 486
  • 6
  • 9
6

Below example will work even with length variation and few more use cases. check out. you can do prototyping as well if you needed.

function sumArray(a, b) {
      var c = [];
      for (var i = 0; i < Math.max(a.length, b.length); i++) {
        c.push((a[i] || 0) + (b[i] || 0));
      }
      return c;
}

// First Use Case.
var a = [1, 2, 3, 4];
var b = [1, 2, 3, 4];
console.log( sumArray(a, b) );

// Second Use Case with different Length.
var a = [1, 2, 3, 4];
var b = [1, 2, 3, 4, 5];
console.log( sumArray(a, b) );

// Third Use Case with undefined values and invalid length.
var a = [1, 2, 3, 4];
var b = [];
b[1] = 2;
b[3] = 4;
b[9] = 9;
console.log( sumArray(a, b) );
Venkat.R
  • 7,420
  • 5
  • 42
  • 63
4

Just merge Popovich and twalters's answer.

Array.prototype.SumArray = function (arr) {

        var sum = this.map(function (num, idx) {
          return num + arr[idx];
        });

        return sum;
    }
var array1 = [1,2,3,4];
var array2 = [5,6,7,8];
var sum = array1.SumArray(array2);
console.log(sum); // [6,8,10,12]
Linmon
  • 41
  • 2
4

For all of the beginners coming across this question who may not be at the level to use map / reduce or ternary operators..

 let sum = 0;
 let nums = []

 for (let i = 0; i < array1.length; i++){
     sum = array1[i] + array2[i];
     nums.push(sum)
   }

 return nums
  • Welcome to Stack Overflow! Nice answer! You should consider [registering an account](/users/signup) to get access to more of Stack Overflow's features. – Hoppeduppeanut Dec 20 '20 at 23:21
3

You can't avoid the loop, but you can do this once and add a function to all Array objects using Array.prototype.

Here's and example:

// Add a SumArray method to all arrays by expanding the Array prototype(do this once in a general place)
Array.prototype.SumArray = function (arr) {
    var sum = [];
    if (arr != null && this.length == arr.length) {
        for (var i = 0; i < arr.length; i++) {
            sum.push(this[i] + arr[i]);
        }
    }

    return sum;
}

// here's your code
var array1 = [1, 2, 3, 4];
var array2 = [5, 6, 7, 8];
var sum = array1.SumArray(array2);
console.log(sum); // [6,8,10,12]

Here's your Fiddle.

Amir Popovich
  • 29,350
  • 9
  • 53
  • 99
  • Breaking encapsulation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain#Bad_practice.3A_Extension_of_native_prototypes – HMR Jun 07 '14 at 07:13
3

Another way to do it could be like that

var array1 = [1,2,3,4];
var array2 = [5,6,7,8];

var sum = [...array1].map((e,i)=> e+array2[i]); //[6,8,10,12]

In this case [...array1] is the same to [1,2,3,4]

2

You can use the _.unzipWith method from the Lodash library.

var array1 = [1, 2, 3, 4];
var array2 = [5, 6, 7, 8];
var array = [array1, array2];
console.log(_.unzipWith(array, _.add));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
Penny Liu
  • 15,447
  • 5
  • 79
  • 98
2

In ES6+, you can use arrow function to make the code clear:

var x = [1,2,3];
var y = [2,3,4];
var sum = x.map( (val, i) => val + y[i] );

console.log(sum); //Array [3, 5, 7]


var z = [3,4,5];
var add3 = x.map( (val, i) => val + y[i] + z[i] );

console.log(add3); //Array [6, 9, 12]
Eric Chang
  • 2,580
  • 4
  • 19
  • 19
1

All the above mentioned answer is correct,

Using reduce. I just want to add my answer might be simple and useful.

var array1 = [1,2,3,4];
var array2 = [5,6,7,8];

const reducer = (accumulator, currentValue, index, array) => {
    let val = currentValue + array2[index];
    accumulator.push(val);
    return accumulator;
}


console.log(array1.reduce(reducer, []));

Thanks..

Javascript Coder
  • 5,691
  • 8
  • 52
  • 98
0

You can do it using some functional style:

const a = [1,2,3]
const b = [4,5,6]

const f= a.concat(b).map((v,i,arr)=>{
  if ( i<arr.length) return v+arr[i+arr.length/2]
}).filter(n=>!isNaN(n))

console.log(f)
rlib
  • 7,444
  • 3
  • 32
  • 40
0

This example will work with different length variation:

let getSum = (arr1, arr2) =>  {
   let main = arr1.length >= arr2.length ? arr1 : arr2;
   let sec = arr1.length < arr2.length ? arr1 : arr2;
   return main.map((elem, i) => sec[i] ? elem + sec[i] : elem)
}
0

Generic solution for N arrays of possibly different lengths using functional programming in one line ;)

const sumArrays = as => as.filter(a => a.length).length ? [as.filter(a => a.length).reduce((r, a) => r + a.shift(), 0), ...sumArrays(as)] : []

console.log(sumArrays([[1, 2, 3], [100], [11, 22, 33, 44], []]))
0

let array1=[];
let array2=[];
let array3=[];
let sum=0;

// Take elements from the user for 1st Array

for(let i=0; i<3; i++){
    array1[i]=Number(prompt(i));
}
console.log(array1);

// Take elements from the user for 2nd Array

for(let j=0; j<3; j++){
    array2[j]=Number(prompt(j));
}
console.log(array2);

// add sum of two arrays in 3rd Array

for(k=0; k<3; k++){
    sum=(array1[k]+array2[k]);
    array3.push(sum);    
}
console.log(array3);
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Mar 16 '22 at 20:25
0

Note: This answer does NOT solve the issue in a single iteration.

Base Case Solution

You can split this issue into two separate issues.

  1. First we need to combine the elements of elements of the different arrays that are present on the same index. This is commonly called "zipping arrays". You'll find a zip() methods in a lot of libraries, but can easily create your own.

    const array1 = [1,2,3,4];
    const array2 = [5,6,7,8];
    
    zip(array1, array2) //=> [ [1,5], [2,6], [3,7], [4,7] ]
    

    If you aren't using a library that has this included, you must define your own. A simple variant looks like this:

    function zip(...arrays) {
      const length = Math.max(...arrays.map(array => array.length));
      return Array.from({ length }, (_, i) => arrays.map(array => array[i]));
    }
    
  2. Now that we have combined the two arrays, we need to sum each of the nested arrays. For this we must first know how to sum values in a normal array.

    Just like zipping arrays, summing them is such a common action that most libraries provide a helper. Check any libraries you're using before defining your own sum().

    A normal array of numbers can produce a sum by using reduce().

    numbers.reduce((sum, number) => sum + number, 0);
    

    It's probably a good idea to store this in a new function definition. sum(numbers) is far more descriptive than the numbers.reduce(...) line.

    function sum(numbers) {
      return numbers.reduce((sum, number) => sum + number, 0);
    }
    

We now have all the building blocks to produce the desired result.

const result = zip(array1, array2).map(numbers => sum(numbers));
//=> [6, 8, 10, 12]

// simplified
const result = zip(array1, array2).map(sum);
//=> [6, 8, 10, 12]

The above combines array1 and array2 like shown in 1. Then we map() each of the resulting pairs to their sum.

const array1 = [1,2,3,4];
const array2 = [5,6,7,8];

const result = zip(array1, array2).map(sum);
console.log(result);

// helpers
function zip(...arrays) {
  const length = Math.max(...arrays.map(array => array.length));
  return Array.from({ length }, (_, i) => arrays.map(array => array[i]));
}

function sum(numbers) {
  return numbers.reduce((sum, number) => sum + number, 0);
}

More Arrays

This solution allows you to easily change the number of arrays.

const result = zip(array1, array2, array3, array4).map(sum);

Non-Matching Array Lengths

Do note that it's expected that all the arrays do have the same length. If the length doesn't match the sum will result in NaN, since number + undefined = NaN

zip([1,2,3], [4,5], [6])
//=> [ [1,4,6], [2,5,undefined], [3,undefined,undefined] ]

To solve this you could add another helper to remove "empty" values. For this we can introduce the compact() helper, which removes null and undefined values from the array.

function compact(array) {
  return array.filter(item => item != null); // removes both `null` and `undefined`
}

Here is an example usage:

zip([1,2,3], [4,5], [6]) // [ [1,4,6], [2,5, undefined], [3,undefined,undefined] ]
  .map(compact)          // [ [1,4,6], [2,5], [3] ]
  .map(sum)              // [ 11, 7, 3 ]

const array1 = [1,2,3];
const array2 = [4,5];
const array3 = [6];

const result = zip(array1, array2, array3).map(compact).map(sum);
console.log(result);

// helpers
function zip(...arrays) {
  const length = Math.max(...arrays.map(array => array.length));
  return Array.from({ length }, (_, i) => arrays.map(array => array[i]));
}

function sum(numbers) {
  return numbers.reduce((sum, number) => sum + number, 0);
}

function compact(array) {
  return array.filter(item => item != null);
}
3limin4t0r
  • 19,353
  • 2
  • 31
  • 52
-1

If you have two arrays with different lengths then here is how you can sum them up.

<pre>
    var array1 = [1,2,3,4,9];
    var array2 = [5,6,7,8];

    sum = [6,8,10,12,9];
</pre>

We can start a new loop and then check if the index exists in the array if not then assign it to 0.

Map

<pre>
    const output = [];

    array1.map((item, i) => {
        output.push((array1[i] ? array1[i] : 0) + (array2[i] ? array2[i] : 0)); 
    });

    console.log(output) // [ 6, 8, 10, 12, 9 ]
</pre>

Reduce

<pre>
    let output = array1.reduce((newArray, item, i) => {
        newArray.push((array1[i] ? array1[i] : 0) + (array2[i] ? array2[i] : 0));
        return newArray;
    }, []);
    console.log(output); // [ 6, 8, 10, 12, 9 ]
</pre>
Ajit Shaw
  • 44
  • 3