ECMAScript 6: the new array methods find() and findIndex()

[2013-12-25] esnext, dev, javascript
(Ad, please don’t block)
Update 2014-05-08. Newer version of this post: “ECMAScript 6’s new array methods

Two new Array methods (proposed by Rick Waldron) are in the latest ECMAScript 6 specification draft:

This blog post describes them.

Array.prototype.find(predicate, thisValue?)

The signature of the callback predicate() is
    predicate(element, index, array)
find() iterates over the array (while skipping holes) and calls predicate for each element. If predicate returns true, find() stops iterating and returns the current element (1). If the callback never returns true, find() returns undefined (2).

This method could be implemented as follows.

    Array.prototype.find = function (predicate, thisValue) {
        var arr = Object(this);
        if (typeof predicate !== 'function') {
            throw new TypeError();
        }
        for(var i=0; i < arr.length; i++) {
            if (i in arr) {  // skip holes
                var elem = arr[i];
                if (predicate.call(thisValue, elem, i, arr)) {
                    return elem;  // (1)
                }
            }
        }
        return undefined;  // (2)
    }

Array.prototype.findIndex(predicate, thisValue?)

This method works like find(), but returns i in line (1) and −1 in line (2).

Finding NaN via findIndex()

It’s a well-known limitation of Array.prototype.indexOf() that it can’t find NaN, because it searches for elements via === [1]:
    > ['a', NaN, 'b'].indexOf(NaN)
    -1
With findIndex(), you can use Object.is() [2] and will have no such problem:
    > ['a', NaN, 'b'].findIndex(y => Object.is(NaN, y))
    1
You can also adopt a more general approach, by creating a helper function elemIs:
    > function elemIs(x) { return Object.is.bind(null, x) }
    > ['a', NaN, 'b'].findIndex(elemIs(NaN))
    1

Availability

As you can see in Kangax’ ECMAScript 6 compatibility table, recent versions of Firefox and Chrome already support the Array.prototype.find*() methods.

Furthermore, Paul Millr’s es6-shim has backported the methods to ECMAScript 5.

References

  1. NaN and Infinity in JavaScript
  2. Stricter equality in JavaScript