Mike Williamson Mike Williamson - 1 year ago 37
Javascript Question

How can I make Javascript's reduce method work on arrays of arrays?

Orig Problem

I was working on an exercise that should sum up the amount of change left in a cash register, variable

looks something like this:

var cid = [["PENNY", 0], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]];

In a case like this, when all of the values are 0, then I should report that the register is empty.

I thought something like this should work:

if (cid.reduce(function(prevVal, curVal) {
return prevVal[1] + curVal[1];
}) === 0)

But it didn't.

Digging In

Some strange things seem to happen when working with arrays within arrays and the
method. For instance:

cid.reduce(function(prevVal, curVal) {
return prevVal[1] + curVal[1];


Whereas, if I just let the entire array through, I do get something, albeit something strange:

cid.reduce(function(prevVal, curVal) {
return prevVal + curVal;


It's clear to me that, when using
, it isn't simply delving one level deeper into the array / object, as I had suspected it would.

However, the only other thing I might have suspected is also wrong: it's not delving into all the levels, either. If this were the case, I would have expected to have seen something like this (notice there are no commas):


Two Questions

  1. Is there any way to effectively use the
    method with multi-dimensional arrays like this?

  2. Can anyone help me understand what is going on under the hood here?

Answer Source

You're slightly misunderstanding the nature of reduce; the value in prevVal is not whatever value we were called with last; it's whatever value we returned last. Since you are returning an integer, prevVal is an integer, and prevVal[1] is undefined.

I'd suggest you alter your call to reduce to provide an explicit default of 0, and rewrite your function to assume that prevVal is always going to be a number, not a value in your array.

var cid = [
  ["PENNY", 0],
  ["NICKEL", 0],
  ["DIME", 0],
  ["QUARTER", 0],
  ["ONE", 0],
  ["FIVE", 0],
  ["TEN", 0],
  ["TWENTY", 0],
  ["ONE HUNDRED", 0]

var val = cid.reduce(function(prevVal, curVal) {
  return prevVal + curVal[1];
}, 0);

document.write("<pre>" + JSON.stringify(val) + '</pre>');