JSMar 12, 2015 · 1 min read

Quirky Behavior with Array.prototype.Reduce

Array.prototype.reduce silently skips the callback when the array has only one element — which means if your object ever has a single key, your reduce-based flattening breaks without warning.

I ran into this issue with reduce when I tried to flatten an object containing arrays.

JavaScript
var myObj = {
  "HomePage": [
    "ModuleA",
    "ModuleB",
    "ModuleC"
  ],
  "ProfilePage": [
    "ModuleB",
    "ModuleC",
    "ModuleD"
  ]
};

My initial approach was to reduce everything with the following:

JavaScript
Object.keys(myObj).reduce(function(a,b) {
  return myObj[a].concat(myObj[b])
});

This works, but will run into an error when your configuration object only has one key. It's as if reduce is not called when the array it is operating on has fewer than two elements.

JavaScript
var smallObj = {
  "HomePage": [
    "ModuleA",
    "ModuleB",
    "ModuleC"
  ]
};

Object.keys(smallObj).reduce(function(a,b) {
    console.log('reducing...');
    return smallObj[a].concat(smallObj[b])
})

If you try to add an initial value of [], it will throw a TypeError: Cannot read property 'concat' of undefined.

JavaScript
Object.keys(smallObj).reduce(function(a,b) {
        return smallObj[a].concat(smallObj[b])
}, []);

Alternative Solution

Suggested by @rouxbot:
JavaScript
Object.keys(smallObj).map(function(key){return smallObj[key]}).reduce(function(a,b) {
  return a.concat(b);
})