First of all, it's considered bad practice to extend Object.prototype
.
(首先, 扩展Object.prototype
被认为是不好的做法 。)
Instead, provide your feature as utility function on Object
, just like there already are Object.keys
, Object.assign
, Object.is
, ...etc.(相反,在Object
上提供您的功能作为实用程序功能,就像已有Object.keys
, Object.assign
, Object.is
,...等。)
I provide here several solutions:
(我在这提供了几个解决方案)
- Using
reduce
and Object.keys
(使用reduce
和Object.keys
)
- As (1), in combination with
Object.assign
(如(1),与Object.assign
结合使用)
- Using
map
and spread syntax instead of reduce
(使用map
和spread语法代替reduce
)
- Using
Object.entries
and Object.fromEntries
(使用Object.entries
和Object.fromEntries
)
1. Using reduce
and Object.keys
(1.使用reduce
和Object.keys
)
With reduce
and Object.keys
to implement the desired filter (using ES6 arrow syntax ):
(使用reduce
和Object.keys
实现所需的过滤器(使用ES6 箭头语法 ):)
Object.filter = (obj, predicate) => Object.keys(obj) .filter( key => predicate(obj[key]) ) .reduce( (res, key) => (res[key] = obj[key], res), {} ); // Example use: var scores = { John: 2, Sarah: 3, Janet: 1 }; var filtered = Object.filter(scores, score => score > 1); console.log(filtered);
Note that in the above code predicate
must be an inclusion condition (contrary to the exclusion condition the OP used), so that it is in line with how Array.prototype.filter
works.
(请注意,在上面的代码predicate
必须是包含条件(与OP使用的排除条件相反),因此它与Array.prototype.filter
工作方式一致。)
2. As (1), in combination with Object.assign
(2.如(1),与Object.assign
结合使用)
In the above solution the comma operator is used in the reduce
part to return the mutated res
object.
(在上面的解决方案中,在reduce
部分中使用逗号运算符来返回变异的res
对象。)
This could of course be written as two statements instead of one expression, but the latter is more concise.(这当然可以写成两个语句而不是一个表达式,但后者更简洁。)
To do it without the comma operator, you could use Object.assign
instead, which does return the mutated object:(要在没有逗号运算符的情况下执行此操作,您可以使用Object.assign
,它会返回变异对象:)
Object.filter = (obj, predicate) => Object.keys(obj) .filter( key => predicate(obj[key]) ) .reduce( (res, key) => Object.assign(res, { [key]: obj[key] }), {} ); // Example use: var scores = { John: 2, Sarah: 3, Janet: 1 }; var filtered = Object.filter(scores, score => score > 1); console.log(filtered);
3. Using map
and spread syntax instead of reduce
(3.使用map
和spread语法代替reduce
)
Here we move the Object.assign
call out of the loop, so it is only made once, and pass it the individual keys as separate arguments (using the spread syntax ):
(这里我们将Object.assign
调用移出循环,因此它只进行一次,并将各个键作为单独的参数传递(使用扩展语法 ):)
Object.filter = (obj, predicate) => Object.assign(...Object.keys(obj) .filter( key => predicate(obj[key]) ) .map( key => ({ [key]: obj[key] }) ) ); // Example use: var scores = { John: 2, Sarah: 3, Janet: 1 }; var filtered = Object.filter(scores, score => score > 1); console.log(filtered);
4. Using Object.entries
and Object.fromEntries
(4.使用Object.entries
和Object.fromEntries
)
As the solution translates the object to an intermediate array and then converts that back to a plain object, it would be useful to make use of Object.entries
(ES2017) and to use a method that does the opposite (ie create an object from an array of key/value pairs ).
(当解决方案将对象转换为中间数组然后将其转换回普通对象时,使用Object.entries
(ES2017)并使用相反的方法(即从中创建对象 )将非常有用。 键/值对数组 )。)
At the time of writing the Object.fromEntries
proposal is at stage 3. Firefox and, more recently, Chrome have implemented it .(在撰写本文时, Object.fromEntries
提案已进入第3阶段.Firefox以及最近Chrome已实现它 。)
Otherwise a polyfill can be used.(否则可以使用填充物。)
It leads to these two "one-liner" methods on Object
(including the polyfill):
(它导致Object
上的这两个“单线”方法(包括polyfill):)
Object.fromEntries = arr => Object.assign({}, ...arr.map( ([k, v]) => ({[k]: v}) )); Object.filter = (obj, predicate) => Object.fromEntries(Object.entries(obj).filter(predicate)); // Example use: var scores = { John: 2, Sarah: 3, Janet: 1 }; var filtered = Object.filter(scores, ([name, score]) => score > 1); console.log(filtered);
The predicate function gets a key/value pair as argument here, which is a bit different, but allows for more possibilities in the predicate function's logic.
(谓词函数在这里获得一个键/值对作为参数,这有点不同,但在谓词函数的逻辑中允许更多的可能性。)