I have two arrays of same length and I would like to somehow process them both at once with the reduce method. Something like:
var arr1 = [2, 3, 4, 5, 6];
var arr2 = [5, 10, 4, 9, 5];
var productSum = arr1.reduce(function(sumOfProducts, item, secondArrayItem) {
/* here I would like to multiply item from arr1 by the item from arr2 at the same index */
return sumOfProducts + item * secondArrayItem;
}, 0, arr2)
console.log(productSum); // 131
An option would of course be to access the correct item from arr2
using currentIndex
, but that solution is ugly as I am accessing a variable outside of the scope of the function.
My specific use case is that I have an array with resources like var resources = [2, 5, 4, 6, 2]
and I want to check if each item is higher than corresponding resource cost in another array like var cost = [3, 1, 0, 0, 1]
.
Is there some nice solution to this using the reduce()
function?
I have two arrays of same length and I would like to somehow process them both at once with the reduce method. Something like:
var arr1 = [2, 3, 4, 5, 6];
var arr2 = [5, 10, 4, 9, 5];
var productSum = arr1.reduce(function(sumOfProducts, item, secondArrayItem) {
/* here I would like to multiply item from arr1 by the item from arr2 at the same index */
return sumOfProducts + item * secondArrayItem;
}, 0, arr2)
console.log(productSum); // 131
An option would of course be to access the correct item from arr2
using currentIndex
, but that solution is ugly as I am accessing a variable outside of the scope of the function.
My specific use case is that I have an array with resources like var resources = [2, 5, 4, 6, 2]
and I want to check if each item is higher than corresponding resource cost in another array like var cost = [3, 1, 0, 0, 1]
.
Is there some nice solution to this using the reduce()
function?
- 2 You'd typically do this by zipping the 2 lists together, then reduce the zipped list. Don't know how to idiomatically zip lists in JS though. – Carcigenicate Commented Jun 6, 2017 at 21:30
-
4
"that solution is ugly as I am accessing a variable outside of the scope of the function." - I don't see what's ugly about that, we do this all the time when accessing globals or using closures. The important thing is just that the variable is constant. What really is ugly about this solution is a) it's not symmetric (accessing arr1 works different than accessing arr2) and b) we didn't ensure that the arrays have the same length, so we don't know whether
arr2[i]
accesses a valid index. – Bergi Commented Jun 6, 2017 at 21:42
3 Answers
Reset to default 2Using Ramda you can first zip the two lists, and then reduce it and use destructuring to extract the array elements and pass them as arguments to the callback:
const reduceTwo = (callback, initialValue, arr1, arr2) =>
R.reduce((acc, [x, y]) => callback(acc, x, y), initialValue, R.zip(arr1, arr2));
const arr1 = [2, 3, 4, 5, 6];
const arr2 = [5, 10, 4, 9, 5];
console.log(reduceTwo((acc, x, y) => acc + x * y, 0, arr1, arr2));
<script src="https://cdnjs.cloudflare./ajax/libs/ramda/0.24.1/ramda.min.js"></script>
The standard way that I know to do this is to bine the 2 lists into a list of corresponding pairs ("zipping"), then reduce the bined lists:
var zipped = zip(arr1, arr2)
reduce((acc, [x, y]) => (Use x and y),
zipped)
For implementations of zip
, see this question.
(Will verify syntax when I got off of transit)
You may do as follows with pure JS;
var arr1 = [2, 3, 4, 5, 6],
arr2 = [5, 10, 4, 9, 5],
result = arr1.reduce((r,c,i) => (r.sum = r.sum ? r.sum + c * r[i] : c * r[i], r), arr2.slice()).sum;
console.log(result);
I .slice()
arr2
in order to not mutate it with a state variable yet you may still do without slicing if you will not apply a for in
loop to arr2
afterwards or such...