En primer lugar, se considera una mala práctica extenderObject.prototype
. En su lugar, proporcionar a su función como función de utilidad en Object
, al igual que ya existen Object.keys
, Object.assign
, Object.is
, ... etc.
Proporciono aquí varias soluciones:
- Usando
reduce
yObject.keys
- Como (1), en combinación con
Object.assign
- Uso
map
y sintaxis extendida en lugar dereduce
- Usando
Object.entries
yObject.fromEntries
1. Usando reduce
yObject.keys
Con reduce
y Object.keys
para implementar el filtro deseado (usando la sintaxis de flecha 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);
Tenga en cuenta que en el código anterior predicate
debe ser una condición de inclusión (contrario a la condición de exclusión que utilizó el OP), de modo que esté en línea con el Array.prototype.filter
funcionamiento.
2. Como (1), en combinación con Object.assign
En la solución anterior, el operador de coma se usa en la reduce
parte para devolver el res
objeto mutado . Por supuesto, esto podría escribirse como dos declaraciones en lugar de una sola expresión, pero esta última es más concisa. Para hacerlo sin el operador de coma, puede usar Object.assign
en su lugar, lo que devuelve el objeto mutado:
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. Uso map
y sintaxis extendida en lugar dereduce
Aquí movemos la Object.assign
llamada fuera del ciclo, por lo que solo se realiza una vez, y le pasamos las teclas individuales como argumentos separados (usando la sintaxis de propagación ):
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
yObject.fromEntries
A medida que la solución traduce el objeto a una matriz intermedia y luego la convierte de nuevo en un objeto plano, sería útil utilizar Object.entries
(ES2017) y lo contrario (es decir, crear un objeto a partir de una matriz de pares clave / valor ) con Object.fromEntries
( ES2019).
Conduce a este método "one-liner" en 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);
La función de predicado obtiene un par clave / valor como argumento aquí, que es un poco diferente, pero permite más posibilidades en la lógica de la función de predicado.