Reputation: 1287
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.
Upvotes: 65
Views: 164154
Reputation: 44
<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.
<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>
<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>
Upvotes: -1
Reputation: 21130
Note: This answer does NOT solve the issue in a single iteration.
You can split this issue into two separate issues.
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]));
}
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);
}
This solution allows you to easily change the number of arrays.
const result = zip(array1, array2, array3, array4).map(sum);
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);
}
Upvotes: 0
Reputation: 1
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);
Upvotes: 0
Reputation: 49
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
Upvotes: 4
Reputation: 5803
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..
Upvotes: 1
Reputation: 2753
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]
Upvotes: 1
Reputation: 1
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], []]))
Upvotes: 0
Reputation: 59
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]
Upvotes: 4
Reputation: 13963
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
Upvotes: 32
Reputation: 1
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)
}
Upvotes: 0
Reputation: 17438
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>
Upvotes: 3
Reputation: 7867
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)
Upvotes: 1
Reputation: 7746
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) );
Upvotes: 7
Reputation: 506
var arr = [1,2,3,4];
var arr2 = [1,1,1,2];
var squares = arr.map((a, i) => a + arr2[i]);
console.log(squares);
Upvotes: 26
Reputation: 41
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]
Upvotes: 4
Reputation: 1234
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]
Upvotes: 109
Reputation: 29836
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.
Upvotes: 3