Primeiro de tudo, é considerado uma prática ruim estender-seObject.prototype
. Em vez disso, fornecer o seu recurso como função utilidade em Object
, assim como já existem Object.keys
, Object.assign
, Object.is
, ... etc.
Eu forneço aqui várias soluções:
- Usando
reduce
eObject.keys
- Como (1), em combinação com
Object.assign
- Usando
map
e espalhando sintaxe em vez dereduce
- Usando
Object.entries
eObject.fromEntries
1. Usando reduce
eObject.keys
Com reduce
e Object.keys
para implementar o filtro desejado (usando a sintaxe de seta 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);
Observe que no código acima predicate
deve ser uma condição de inclusão (ao contrário da condição de exclusão usada pelo OP), para que esteja alinhado com o Array.prototype.filter
funcionamento.
2. Como (1), em combinação com Object.assign
Na solução acima, o operador de vírgula é usado na reduce
parte para retornar o res
objeto mutado . Obviamente, isso pode ser escrito como duas declarações em vez de uma expressão, mas a última é mais concisa. Para fazê-lo sem que o operador vírgula, você poderia usar Object.assign
em vez disso, o que faz retornar o objeto mutante:
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. Usando map
e espalhar sintaxe em vez dereduce
Aqui, movemos a Object.assign
chamada para fora do loop, para que seja feita apenas uma vez e passamos as chaves individuais como argumentos separados (usando a sintaxe de propagação ):
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. Usando Object.entries
eObject.fromEntries
Como a solução converte o objeto em uma matriz intermediária e depois a converte em um objeto simples, seria útil usar Object.entries
(ES2017) e o oposto (por exemplo, criar um objeto a partir de uma matriz de pares de chave / valor ) comObject.fromEntries
( ES2019).
Isso leva a esse método "one-liner" em 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);
A função predicado obtém um par de chave / valor como argumento aqui, que é um pouco diferente, mas permite mais possibilidades na lógica da função predicada.