19

I have two arrays of equal length, and I need to multiply the corresponding (by index) values in each, and sum the results.

For example

var arr1 = [2,3,4,5];
var arr2 = [4,3,3,1];

would result in 34 (4*2+3*3+4*3+5*1).

What's the simplest to read way to write this?

4
  • 2
    How odd! All these answers were posted at the same time, so there's no way we saw eachother's answers... look at the name of the variable we chose for the for... loop - everyone picked i. Creepy, huh? Commented Jul 28, 2011 at 21:54
  • Four results, all essentially identical... which to upvote? :P Commented Jul 28, 2011 at 21:55
  • @Reid upvote my recursive version, even though I'd never actually do it that way for this particular problem in JS, it's different! Commented Jul 28, 2011 at 21:58
  • 1
    I upvoted everyone else's answers! :) Commented Jul 29, 2011 at 16:42

16 Answers 16

23
var arr1 = [2,3,4,5];
var arr2 = [4,3,3,1];
console.log(arr1.reduce(function(r,a,i){return r+a*arr2[i]},0));
34

This shows the "functional" approach rather than the "imperative" approach for calculating the dot product of two vectors. Functional approach (which tends to be more concise) is preferred in such a simple function implementation as requested by the OP.

Sign up to request clarification or add additional context in comments.

1 Comment

please explain why this helps the OP
14
var sum = 0;
for(var i=0; i< arr1.length; i++) {
    sum += arr1[i]*arr2[i];
}

1 Comment

The second line can also be written as for(var i=0; i<arr1.length; sum+=arr1[i]*arr2[i], i++);
7
var a = [1,2,3,4,5];
var b = [5,4,3,2,1];

a.map(function(x, index){ //here x = a[index]
 return b[index] + x 
});

=>[6,6,6,6,6]

//if you want to add the elements of an array:

a.reduce(function(x, y){
 return x + y
});

=>15

You can read about Array.map here. and Array.reduce here

Comments

5

Other answers are almost certainly more efficient, but just to give you a recursive viewpoint (it's nicer in some other languages). It does assume the two arrays are of equal length as you didn't specify what to do if they're not.

function sumProducts(array1, array2) {
    if(array1.length) 
        return array1.pop() * array2.pop() + sumProducts(array1, array2);

    return 0;
}

Edit:

katspaugh suggested flipping the returns which is ever so slightly more efficient (don't have to ! the length).

Comments

4
var arr1 = [2,3,4,5];
var arr2 = [4,3,3,1];


var result = 0;
for (var i=0; i < arr1.length; i++) {
  result += (arr1[i] * arr2[i]);
}

alert(result);

Try it here: http://jsfiddle.net/VQKPt/

1 Comment

Whoever is downvoting all these correct answers needs to stop and explain their reason. Or just stop.
3
var i, result = 0;
for(i = 0; i < arr1.length; i++)
    result += arr1[i]*arr2[i];
alert(result);

Not that this will cause an error if arr2 is shorter than arr1, but you said they're equal length, so I didn't bother checking for it.

Comments

3

My vote for simplest-to-read way to write this goes to the humble for loop:

var ii, sumOfProds = 0;
for (ii = 0; ii < arr1.length && ii < arr2.length; ii++) {
    sumOfProds += arr1[ii] * arr2[ii];
}

Comments

3
function mul (arr1, arr2) {
    var n_array = (arr1,arr2).map(x => x * x)
    return n_array
    }
var a = [1,2,3]
var b = [1,2,3]
console.log(mul(a,b))

Comments

2

Something like this:

var sum = 0;
for (var i=0, len = arr1.length; i < len; i++) {     // optimized looping
   sum += arr1[i] * arr2[i];
}

Comments

2

This seems pretty straight forward to me

var result=0;
for (var i=0; i<arr1.length;i++){
    result+=arr1[i]*arr2[i];   
}

Comments

2

A single-line solution using ES6 .reduce():

const sum_products = arr1.reduce((sum, val, i) => sum + (val * arr2[i]), 0)

Comments

1

Declare functions that does the operations you want.

var sum      = function(a, b){ return a + b; };
var subtract = function(a, b){ return a - b; };
var multiply = function(a, b){ return a * b; };
var divide   = function(a, b){ return a / b; };

Then you have a very readable way to perform any operation on two arrays like this:

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

operateArrays(array1, array2, sum);      //[3, 6, 11]
operateArrays(array1, array2, subtract); //[-1, -2, -5]
operateArrays(array1, array2, multiply); //[2, 8, 24]
operateArrays(array1, array2, divide);   //[0.5, 0.5, 0.375]

Using this function

/**
* Divide each number of an array of numbers by another array of numbers
* @param  {Array}    arrayA  The array of numbers
* @param  {Array}    arrayB  The array of numbers
* @param  {Function} fn      Function that performs an operation
* @return {Array}            The resulting array
* @author Victor N. www.vitim.us
*/
function operateArrays(arrayA, arrayB, fn){
    if(arrayA.length!==arrayB.length) throw new Error("Cannot operate arrays of different lengths");
    return arrayB.map(function(b, i){
        return fn(arrayA[i], b);
    });
}

Comments

1
var arr = [1,2,3,4];
var arr2 = [1,1,1,2];

You can use:

var squares = arr.concat(arr2).reduce((t,n)=>t+n);

or:

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

console.log(squares);

2 Comments

If there is no multiplication how does this solve the problem?
I actually tested this using excels sumproduct function, and then did it by hand to confirm, the answer is 14 in your example, but javascript is returning 15
1

Here are 3 functions that all accomplish the same thing. They are listed in order of increasingly modern JavaScript syntax.

The first function uses basic language features that have been around since the beginning. This will work on really old browsers such as IE6.

The second function uses features from ECMASScript 5 which was introduced around 2009, and will work on IE9+.

The third function uses ECMASScript 2015 arrow functions and will not work on any version of IE, not even IE 11 unless you are using some type of build-step in your code to transpile down to ES5 like Babel or Typescript

/**
 * Multiplies the corresponding values of two arrays and then sums the product.
 * Supported in all legacy browsers
 * @param {number[]} arr1 The first array
 * @param {number[]} arr2 The second array
 **/
function sumOfProductsECMAScript4(arr1, arr2) {
    var total = 0;
    for(var i = 0; i < arr1.length; i += 1) {
        total += arr1[i] * arr2[i];
    }
}

/**
 * Multiplies the corresponding values of two arrays and then sums the product.
 * Supported in all mainstream browsers except IE 8 and older.
 * @param {number[]} arr1 The first array
 * @param {number[]} arr2 The second array
 **/
function sumOfProductsECMASScript5(arr1, arr2) {
    // The map function creates a new array of the product of arr1 and arr2 values
    // The reduce function then takes this array of products and adds up all the values
    return arr1
        .map(function (value, index) { return value * arr2[index]; })
        .reduce(function (sum, current) { return sum + current; }, 0);
}

/**
 * Multiplies the corresponding values of two arrays and then sums the product.
 * Supported in all mainstream browsers except IE.
 * @param {number[]} arr1 The first array
 * @param {number[]} arr2 The second array
 **/
function sumOfProductsECMASScript2015(arr1, arr2) {
    // The map function creates a new array of the product of arr1 and arr2 values
    // The reduce function then takes this array of products and adds up all the values
    return arr1
        .map((v, i) => v * arr2[i])
        .reduce((sum, v) => sum + v, 0);
}



// Define your arrays
let arr1 = [2,3,4,5];
let arr2 = [4,3,3,1];

// Usage
let answer = sumOfProductsECMASScript4(arr1, arr2);
let answer2 = sumOfProductsECMASScript5(arr1, arr2);
let answer3 = sumOfProductsECMASScript2015(arr1, arr2);

Comments

0

if you were doing much of this kind of thing, you would probably use a library like mathjs:

var arr1 = [2,3,4,5];
var arr2 = [4,3,3,1];
result=math.dot(arr1,arr2);

Comments

0

make it map and reduce

var arr1 = [2,3,4,5];
var arr2 = [4,3,3,1];

var result = arr1.map((v,i) => v * arr2[i]).reduce((x, y) => x + y, 0)

console.log(result)

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.