short-circuiting Array.prototype.reduce

Kyle Simpson getify at
Fri Mar 27 01:22:39 UTC 2015

> The example code isn't very compelling either; something more real-world would be good

I recently ran across a usage of `reduce(..)` that could have benefitted from an early return. Figured I'd just drop it here for posterity sake, in case anything ever comes of this idea.

I had an array of arrays (2-dimensional array), where each inner array had a list of simple string/number elements (none of them falsy) that could have some repetition within the inner array. I wanted to filter the outer array (the list of the inner arrays) based on whether an inner array had any adjacent duplicates. That is, `[1,4,2,4]` is fine to keep but `[2,4,4,5]` should be filtered out.

Since `reduce(..)` conveniently can compare two adjacent elements if you always return the current value, I decided to model the inner check as a `reduce(..)` that reduces from the original array value to either a `false` or a truthy value (the last element of the inner array element). This reduction result then is how `filter(..)` decides to keep or discard. The reason an early exit would be nice is that as soon as you run across an adjacency-duplication, no more reduction is necessary -- you can immediately "reduce" to `false`.

Here's how I did it, which worked but which was slightly less appealing:

var outer = [
  // [1,2,1,3,4,2]
  // ["foo","bar","bar",10,"foo"]
  // ..

outer = outer.filter(function filterer(inner){
  return inner.reduce(function reducer(prev,current){
    if (prev === false || prev === current) return false;
    return current;

The reduction initial-value is omitted, so it's `undefined`, which never matches any of the `inner` contents.

The `prev === false` check is the way that I fake the "early exit", by which once the reduction value is tripped to `false`, that's always the result for the rest of the reduction.

There's lots of other ways to "slice" that problem, I know. But reduction was attractive except for its lack of early exit.

More information about the es-discuss mailing list