ECMAScript 5 tiene el filter()
prototipo para los Array
tipos, pero no para los Object
tipos, si lo entiendo correctamente.
¿Cómo implementaría un filter()
for Object
s en JavaScript?
Digamos que tengo este objeto:
var foo = {
bar: "Yes"
};
Y quiero escribir un filter()
que funcione en Object
s:
Object.prototype.filter = function(predicate) {
var result = {};
for (key in this) {
if (this.hasOwnProperty(key) && !predicate(this[key])) {
result[key] = this[key];
}
}
return result;
};
Esto funciona cuando lo uso en la siguiente demostración, pero cuando lo agrego a mi sitio que usa jQuery 1.5 y jQuery UI 1.8.9, obtengo errores de JavaScript en FireBug.
javascript
jquery
object
filtering
AgileMeansDoAsLittleAsPossible
fuente
fuente
Object.prototype
: bugs.jquery.com/ticket/2721Respuestas:
Nunca se extienda
Object.prototype
.Cosas horribles sucederán con su código. Las cosas se romperán. Estás extendiendo todos los tipos de objetos, incluidos los literales de objetos.
Aquí hay un ejemplo rápido que puedes probar:
En su lugar, cree una función en la que pase el objeto.
fuente
Object.prototype
, sino simplemente colocar la funciónObject
. Segundo, este es el código del OP . Claramente, la intención de OP es.filter()
ser tal que filtre los resultados positivos. En otras palabras, es un filtro negativo, donde un valor de retorno positivo significa que está excluido del resultado. Si observa el ejemplo jsFiddle, está filtrando las propiedades existentes que sonundefined
.Object.prototype
. De la pregunta: "Esto funciona ..., pero cuando lo agrego a mi sitio ..., obtengo errores de JavaScript" Si OP decide implementar un.filter()
con el comportamiento opuesto al de esoArray.prototpe.filter
, eso depende de él / ella. Deje un comentario debajo de la pregunta si desea notificar a OP que el código está mal, pero no me diga que lo estoy haciendo mal cuando no es mi código.En primer lugar, se considera una mala práctica extender
Object.prototype
. En su lugar, proporcionar a su función como función de utilidad enObject
, al igual que ya existenObject.keys
,Object.assign
,Object.is
, ... etc.Proporciono aquí varias soluciones:
reduce
yObject.keys
Object.assign
map
y sintaxis extendida en lugar dereduce
Object.entries
yObject.fromEntries
1. Usando
reduce
yObject.keys
Con
reduce
yObject.keys
para implementar el filtro deseado (usando la sintaxis de flecha ES6 ):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 elArray.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 elres
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 usarObject.assign
en su lugar, lo que devuelve el objeto mutado: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 ):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 ) conObject.fromEntries
( ES2019).Conduce a este método "one-liner" en
Object
: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.
fuente
x => x.Expression.Filters.Filter
.Filter
está al final, pero si es una función, debe llamarlo (x => x.Expression.Filters.Filter()
)Si está dispuesto a usar guiones bajos o lodash , puede usar
pick
(o su opuestoomit
).Ejemplos de documentos de subrayado:
O con una devolución de llamada (para lodash , use pickBy ):
fuente
Enfoque ES6 ...
Imagina que tienes este objeto a continuación:
Crea una función:
Y llámalo:
y va a volver :
fuente
!predicate
su propio código).Como Patrick ya dijo, esta es una mala idea, ya que casi con seguridad romperá cualquier código de terceros que pueda desear usar.
Todas las bibliotecas, como jquery o prototype, se romperán si extiende
Object.prototype
, la razón es que la iteración perezosa sobre los objetos (sinhasOwnProperty
verificaciones) se romperá, ya que las funciones que agregue serán parte de la iteración.fuente
Qué tal si:
O...
fuente
Dado
luego :
Mostrar fragmento de código
fuente
He creado un
Object.filter()
que no solo se filtra por una función, sino que también acepta una serie de claves para incluir. El tercer parámetro opcional le permitirá invertir el filtro.Dado:
Formación:
Función:
Código
Descargo de responsabilidad : elegí usar Ext JS core por brevedad. No sentí que fuera necesario escribir verificadores de tipos para los tipos de objetos ya que no era parte de la pregunta.
fuente
Mi solución obstinada:
Casos de prueba:
https://gist.github.com/bernardoadc/872d5a174108823159d845cc5baba337
fuente
Solución en Vanilla JS del año 2020.
Puede filtrar
romNumbers
objetos por clave:O filtrar
romNumbers
objeto por valor:fuente
Si desea mutar el mismo objeto en lugar de crear uno nuevo.
El siguiente ejemplo eliminará todos los 0 o valores vacíos:
fuente
Como todos decían, no te metas con el prototipo. En cambio, simplemente escriba una función para hacerlo. Aquí está mi versión con
lodash
:fuente
Lo uso cuando lo necesito:
fuente
En estos casos, uso el jquery $ .map, que puede manejar objetos. Como se menciona en otras respuestas, no es una buena práctica cambiar los prototipos nativos ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain#Bad_practice_Extension_of_native_prototypes )
A continuación se muestra un ejemplo de filtrado simplemente marcando alguna propiedad de su objeto. Devuelve el propio objeto si su condición es verdadera o devuelve
undefined
si no. Laundefined
propiedad hará que ese registro desaparezca de su lista de objetos;fuente
$.map
puede tomar un objeto, pero devuelve una matriz, por lo que se pierden los nombres de propiedad originales. El OP necesita un objeto plano filtrado.