Прежде всего, расширение считается плохой практикойObject.prototype
. Вместо этого, обеспечить вашу функцию в качестве функции полезности на Object
, так же , как там уже есть Object.keys
, Object.assign
, Object.is
... и т.д..
Я приведу здесь несколько решений:
- Использование
reduce
иObject.keys
- Как (1), в сочетании с
Object.assign
- Использование
map
и распространение синтаксиса вместоreduce
- Использование
Object.entries
иObject.fromEntries
1. Использование reduce
иObject.keys
С помощью 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);
Обратите внимание, что в приведенном выше коде predicate
должно быть условие включения (в отличие от условия исключения используемого OP), чтобы оно соответствовало тому, как Array.prototype.filter
работает.
2. Как (1), в сочетании с Object.assign
В приведенном выше решении оператор запятой используется в reduce
части для возврата мутированного res
объекта. Конечно, это можно записать в виде двух утверждений вместо одного выражения, но последнее является более кратким. Для того, чтобы сделать это без оператора запятая, вы можете использовать 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. Использование map
и распространение синтаксиса вместоreduce
Здесь мы перемещаем 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. Использование Object.entries
иObject.fromEntries
Поскольку решение переводит объект в промежуточный массив, а затем преобразует его обратно в простой объект, было бы полезно использовать Object.entries
(ES2017) и наоборот (т.е. создать объект из массива пар ключ / значение ) с помощью Object.fromEntries
( ES2019).
Это приводит к этому «однострочному» методу Object
:
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);
Функция предиката получает здесь пару ключ / значение в качестве аргумента, которая немного отличается, но допускает больше возможностей в логике функции предиката.