Remember back when we discussed Array#partition
? Cool, because having a partition
method makes these next two a breeze!
/** * Return the group of elements for which the iterator's return value is true. * * @param {Function} iterator The iterator receives each element in turn as * the first agument. * @param {Object} [context] Optional context parameter to be * used as `this` when calling the iterator function. * * @type Array * @returns An array containing the elements for which the iterator returned true. */ Array.prototype.select = function(iterator, context) { return this.partition(iterator, context)[0]; }; /** * Return the group of elements for which the iterator's return value is false. * * @param {Function} iterator The iterator receives each element in turn as * the first agument. * @param {Object} [context] Optional context parameter to be * used as `this` when calling the iterator function. * * @type Array * @returns An array containing the elements for which the iterator returned false. */ Array.prototype.reject = function(iterator, context) { return this.partition(iterator, context)[1]; };
We can cheat quite a bit by delegating the brunt of the work to partition
and just return the partition that matches what we want, the true partition in the case of select
, and the false partition in the case of reject
.
Another thing to note is that in most modern browsers JavaScript already has an equivalent method to select
implemented. It’s called filter
. It may make sense to use select
as an alias for filter
, in the cases where it exists.
The important thing to notice is that by implementing robust extensions that are general it opens the door for simpler implementations of specific common cases. This in turn leads to an increase in consistency and a reduction of errors because there is only one method that does the real work instead of several similar methods. When the code changes there is only one place necessary to make the change in rather than many places, and that’s always a good thing.