First of all, it is considered bad practice to extend Object.prototype . Instead, provide your function as a utility function for Object , just like there are already Object.keys , Object.assign , Object.is , ... etc.
I will give a few solutions here:
- Using
reduce and Object.keys - Like (1), combined with
Object.assign - Using
map and distributing syntax instead of reduce - Using
Object.entries and Object.fromEntries
1. Using reduce and Object.keys
With reduce and Object.keys implement the required filter (using ES6 arrow syntax ):
Object.filter = (obj, predicate) => Object.keys(obj) .filter( key => predicate(obj[key]) ) .reduce( (res, key) => (res[key] = obj[key], res), {} );
Note that in the code above, predicate must be an inclusion condition (contrary to the exception condition used by the OP) so that it matches Array.prototype.filter by Array.prototype.filter .
2. Like (1), combined with Object.assign
In the above solution, the comma operator is used in the reduce part to return the mutated res object. Of course, this can be written as two statements instead of a single expression, but the latter is more concise. To do this without a comma operator, you can instead use Object.assign , which returns a mutated object:
Object.filter = (obj, predicate) => Object.keys(obj) .filter( key => predicate(obj[key]) ) .reduce( (res, key) => Object.assign(res, { [key]: obj[key] }), {} );
3. Using map and syntax propagation instead of reduce
Here we move the call to Object.assign from the loop so that it is executed only once, and pass it the individual keys as separate arguments (using the extension syntax ):
Object.filter = (obj, predicate) => Object.assign(...Object.keys(obj) .filter( key => predicate(obj[key]) ) .map( key => ({ [key]: obj[key] }) ) );
4. Using Object.entries and Object.fromEntries
Since the solution translates the object into an intermediate array, and then converts it back to a simple object, it would be useful to use Object.entries (ES2017) and use a method that does the opposite (i.e. creates an object from an array of key / value pairs ). At the time of writing Object.fromEntries proposal in step 3. Firefox and, more recently, Chrome have implemented it . Otherwise, you can use polyfill.
This leads to these two βsingle-lineβ methods on Object (including polyfill):
Object.fromEntries = arr => Object.assign({}, ...arr.map( ([k, v]) => ({[k]: v}) )); Object.filter = (obj, predicate) => Object.fromEntries(Object.entries(obj).filter(predicate));
The predicate function here receives a key / value pair as an argument, which is slightly different, but allows more possibilities in the logic of the predicate function.
trincot Jun 03 '16 at 13:46 on 2016-06-03 13:46
source share