objects es6 ejemplo array filter ecmascript-6

filter - ejemplo - Filtrar propiedades de objeto por clave en ES6



reduce javascript (19)

Ahora puede hacerlo más corto y simple utilizando el método Object.fromEntries (consulte el soporte del navegador):

const obj = { item1: { key: ''sdfd'', value:''sdfd'' }, item2: { key: ''sdfd'', value:''sdfd'' }, item3: { key: ''sdfd'', value:''sdfd'' } }; const keys = [''item1'', ''item3'']; function keysReduce (obj, keys) { return keys.reduce((acc, key) => { if(obj[key] !== undefined) { acc[key] = obj[key]; } return acc; }, {}); }; function forInCompose (obj, keys) { const returnObj = {}; for (const key in obj) { if(keys.includes(key)) { returnObj[key] = obj[key] } }; return returnObj; }; keysReduce(obj, keys); // Faster if the list of allowed keys are short forInCompose(obj, keys); // Faster if the number of object properties are low

Leer más sobre: Object.fromEntries

Digamos que tengo un objeto:

{ item1: { key: ''sdfd'', value:''sdfd'' }, item2: { key: ''sdfd'', value:''sdfd'' }, item3: { key: ''sdfd'', value:''sdfd'' } }

Quiero crear otro objeto filtrando el objeto de arriba, así que tengo algo así.

{ item1: { key: ''sdfd'', value:''sdfd'' }, item3: { key: ''sdfd'', value:''sdfd'' } }

Estoy buscando una manera limpia de lograr esto usando Es6, por lo que los operadores de propagación están disponibles para mí. ¡Gracias!


Así es como lo hice recientemente:

const raw = { item1: { key: ''sdfd'', value: ''sdfd'' }, item2: { key: ''sdfd'', value: ''sdfd'' }, item3: { key: ''sdfd'', value: ''sdfd'' } }; const filteredKeys = [''item1'', ''item3'']; const filtered = Object.assign({}, ...filteredKeys.map(key=> ({[key]:raw[key]})));


Durante el ciclo, no devuelva nada cuando se encuentren ciertas propiedades / claves y continúe con el resto:

const loop = product => Object.keys(product).map(key => { if (key === "_id" || key === "__v") { return; } return ( <ul className="list-group"> <li> {product[key]} <span> {key} </span> </li> </ul> ); });


Esta función filtrará un objeto basado en una lista de claves, es más eficiente que la respuesta anterior ya que no tiene que usar Array.filter antes de llamar a reduce. entonces su O (n) en oposición a O (n + filtrado)

const loop = product => Object.keys(product).map(key => { if (key === "_id" || key === "__v") { return; } return ( <ul className="list-group"> <li> {product[key]} <span> {key} </span> </li> </ul> ); });


Hay muchas formas de lograr esto. La respuesta aceptada utiliza un enfoque Keys-Filter-Reduce, que no es el más eficaz.

En cambio, usar un for...in loop para recorrer las teclas de un objeto, o recorrer las teclas permitidas, y luego componer un nuevo objeto es ~ 50% más de rendimiento a .

const raw = { item1: { prop:''1'' }, item2: { prop:''2'' }, item3: { prop:''3'' } }; const allowed = [''item1'', ''item3'']; const filtered = Object.fromEntries(Object.entries(raw).filter(([key, val])=>allowed.includes(key)));

a. Ver jsPerf para los puntos de referencia de un caso de uso simple. Los resultados diferirán según los navegadores.


La forma más limpia que puedes encontrar es con Lodash#pick

const _ = require(''lodash''); const allowed = [''item1'', ''item3'']; const obj = { item1: { key: ''sdfd'', value:''sdfd'' }, item2: { key: ''sdfd'', value:''sdfd'' }, item3: { key: ''sdfd'', value:''sdfd'' } } const filteredObj = _.pick(obj, allowed)


Las respuestas aquí son definitivamente adecuadas, pero son un poco lentas porque requieren recorrer la lista blanca para cada propiedad del objeto. La solución a continuación es mucho más rápida para grandes conjuntos de datos porque solo recorre la lista blanca una vez:

const data = { allowed1: ''blah'', allowed2: ''blah blah'', notAllowed: ''woah'', superSensitiveInfo: ''whooooah'', allowed3: ''bleh'' }; const whitelist = [''allowed1'', ''allowed2'', ''allowed3'']; function sanitize(data, whitelist) { return whitelist.reduce( (result, key) => data[key] !== undefined ? Object.assign(result, { [key]: data[key] }) : result, {} ); } sanitize(data, whitelist)


Nada que no se haya dicho antes, pero para combinar algunas respuestas a una respuesta general de ES6:

const raw = { item1: { key: ''sdfd'', value: ''sdfd'' }, item2: { key: ''sdfd'', value: ''sdfd'' }, item3: { key: ''sdfd'', value: ''sdfd'' } }; const filteredKeys = [''item1'', ''item3'']; const filtered = filteredKeys .reduce((obj, key) => ({ ...obj, [key]: raw[key] }), {}); console.log(filtered);


Piggybacking en la respuesta de ssube .

Aquí hay una versión reutilizable.

Object.filterByKey = function (obj, predicate) { return Object.keys(obj) .filter(key => predicate(key)) .reduce((out, key) => { out[key] = obj[key]; return out; }, {}); }

Para llamarlo use

const raw = { item1: { key: ''sdfd'', value:''sdfd'' }, item2: { key: ''sdfd'', value:''sdfd'' }, item3: { key: ''sdfd'', value:''sdfd'' } }; const allowed = [''item1'', ''item3'']; var filtered = Object.filterByKey(raw, key => return allowed.includes(key)); }); console.log(filtered);

Lo bueno de las funciones de flecha de ES6 es que no tiene que pasar allowed como parámetro.


Puede agregar un ofilter genérico (implementado con material genérico) para que pueda filtrar fácilmente los objetos de la misma manera que puede hacer arreglos:

const oreduce = (f, acc, o) => Object .entries (o) .reduce ( (acc, [ k, v ]) => f (acc, v, k, o) , acc ) const ofilter = (f, o) => oreduce ( (acc, v, k, o)=> f (v, k, o) ? Object.assign (acc, {[k]: v}) : acc , {} , o )

Podemos verlo trabajando aquí.

const data = { item1: { key: ''a'', value: 1 } , item2: { key: ''b'', value: 2 } , item3: { key: ''c'', value: 3 } } console.log ( ofilter ( (v, k) => k !== ''item2'' , data ) // [ { item1: { key: ''a'', value: 1 } } // , { item3: { key: ''c'', value: 3 } } // ] , ofilter ( x => x.value === 3 , data ) // [ { item3: { key: ''c'', value: 3 } } ] )

Verifique los resultados en su propio navegador a continuación:

const oreduce = (f, acc, o) => Object .entries (o) .reduce ( (acc, [ k, v ]) => f (acc, v, k, o) , acc ) const ofilter = (f, o) => oreduce ( (acc, v, k, o)=> f (v, k, o) ? Object.assign (acc, { [k]: v }) : acc , {} , o ) const data = { item1: { key: ''a'', value: 1 } , item2: { key: ''b'', value: 2 } , item3: { key: ''c'', value: 3 } } console.log ( ofilter ( (v, k) => k !== ''item2'' , data ) // [ { item1: { key: ''a'', value: 1 } } // , { item3: { key: ''c'', value: 3 } } // ] , ofilter ( x => x.value === 3 , data ) // [ { item3: { key: ''c'', value: 3 } } ] )

Estas dos funciones podrían implementarse de muchas maneras. Elegí adjuntar a Array.prototype.reduce dentro de oreduce pero podría escribirlo todo desde cero


Puedes eliminar una clave específica de tu objeto

items={ item1: { key: ''sdfd'', value:''sdfd'' }, item2: { key: ''sdfd'', value:''sdfd'' }, item3: { key: ''sdfd'', value:''sdfd'' } } // Example 1 var key = "item2"; delete items[key]; // Example 2 delete items["item2"]; // Example 3 delete items.item2;


Puedes hacer algo como esto:

const base = { item1: { key: ''sdfd'', value:''sdfd'' }, item2: { key: ''sdfd'', value:''sdfd'' }, item3: { key: ''sdfd'', value:''sdfd'' } }; const filtered = ( source => { with(source){ return {item1, item3} } } )(base); // one line const filtered = (source => { with(source){ return {item1, item3} } })(base);

Esto funciona pero no está muy claro, además de que no se recomienda la declaración with ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with ).


Se puede lograr una solución más simple sin usar filter con Object.entries() lugar de Object.keys()

const raw = { item1: { key: ''sdfd'', value:''sdfd'' }, item2: { key: ''sdfd'', value:''sdfd'' }, item3: { key: ''sdfd'', value:''sdfd'' } }; const allowed = [''item1'', ''item3'']; const filtered = Object.entries(raw).reduce((acc,elm)=>{ const [k,v] = elm if (allowed.includes(k)) { acc[k] = v } return acc },{})


Si está de acuerdo con el uso de la sintaxis de ES6, creo que la forma más limpia de hacerlo, como se señala here y here es:

const data = { item1: { key: ''sdfd'', value:''sdfd'' }, item2: { key: ''sdfd'', value:''sdfd'' }, item3: { key: ''sdfd'', value:''sdfd'' } }; const { item2, ...newData } = data;

Ahora, newData contiene:

{ item1: { key: ''sdfd'', value:''sdfd'' }, item3: { key: ''sdfd'', value:''sdfd'' } };

O, si tiene la clave almacenada como una cadena:

const key = ''item2''; const { [key]: _, ...newData } = data;

En el último caso, [key] se convierte en item2 pero dado que está utilizando una asignación const , debe especificar un nombre para la asignación. _ representa un valor de descarte.

Más generalmente:

const { item2, ...newData } = data; // Assign item2 to item2 const { item2: someVarName, ...newData } = data; // Assign item2 to someVarName const { item2: _, ...newData } = data; // Assign item2 to _ const { [''item2'']: _, ...newData } = data; // Convert string to key first, ...

Esto no solo reduce su operación a una sola línea, sino que tampoco requiere que sepa cuáles son las otras claves (las que desea conservar).


Si tiene una lista de valores permitidos, puede retenerlos fácilmente en un objeto usando:

const raw = { item1: { key: ''sdfd'', value:''sdfd'' }, item2: { key: ''sdfd'', value:''sdfd'' }, item3: { key: ''sdfd'', value:''sdfd'' } }; const allowed = [''item1'', ''item3'']; const filtered = Object.keys(raw) .filter(key => allowed.includes(key)) .reduce((obj, key) => { obj[key] = raw[key]; return obj; }, {}); console.log(filtered);

Esto usa:

  1. Object.keys para enumerar todas las propiedades en raw (los datos originales), luego
  2. Array.prototype.filter para seleccionar las claves que están presentes en la lista permitida, utilizando
    1. Array.prototype.includes para asegurarse de que estén presentes
  3. Array.prototype.reduce para construir un nuevo objeto con solo las propiedades permitidas.

Esto hará una copia superficial con las propiedades permitidas (pero no copiará las propiedades en sí).

También puede usar el operador de propagación de objetos para crear una serie de objetos sin mutarlos (gracias a rjerue por mencionar esto ):

const raw = { item1: { key: ''sdfd'', value:''sdfd'' }, item2: { key: ''sdfd'', value:''sdfd'' }, item3: { key: ''sdfd'', value:''sdfd'' } }; const allowed = [''item1'', ''item3'']; const filtered = Object.keys(raw) .filter(key => allowed.includes(key)) .reduce((obj, key) => { return { ...obj, [key]: raw[key] }; }, {}); console.log(filtered);

Para fines de trivia, si desea eliminar los campos no deseados de los datos originales (lo que no recomendaría hacer, ya que implica algunas mutaciones feas), puede invertir la verificación de inclusiones de la siguiente manera:

const raw = { item1: { key: ''sdfd'', value:''sdfd'' }, item2: { key: ''sdfd'', value:''sdfd'' }, item3: { key: ''sdfd'', value:''sdfd'' } }; const allowed = [''item1'', ''item3'']; Object.keys(raw) .filter(key => !allowed.includes(key)) .forEach(key => delete raw[key]); console.log(raw);

Incluyo este ejemplo para mostrar una solución basada en la mutación, pero no sugiero usarla.


Solo otra solución en una línea de código .

Estaba jugando con la función " Destructuring ":

const raw = { item1: { key: ''sdfd'', value: ''sdfd'' }, item2: { key: ''sdfd'', value: ''sdfd'' }, item3: { key: ''sdfd'', value: ''sdfd'' } }; var myNewRaw = (({ item1, item3}) => ({ item1, item3 }))(raw); console.log(myNewRaw);


ok, ¿qué tal este one-liner

const dummyObj = Object.assign({}, obj); delete dummyObj[key]; const target = Object.assign({}, {...dummyObj});


Bien, ¿qué tal esto?

filteredObject(myData, [''item2'']); //{item1: { key: ''sdfd'', value:''sdfd'' }, item3: { key: ''sdfd'', value:''sdfd'' }}

y llámalo así:

function filterObjectByKeys (object, keys) { return Object.keys(object).reduce((accum, key) => { if (keys.includes(key)) { return { ...accum, [key]: object[key] } } else { return accum } }, {}) }


const myData = { item1: { key: ''sdfd'', value:''sdfd'' }, item2: { key: ''sdfd'', value:''sdfd'' }, item3: { key: ''sdfd'', value:''sdfd'' } }; function filteredObject(obj, filter) { if(!Array.isArray(filter)) { filter = [filter.toString()]; } const newObj = {}; for(i in obj) { if(!filter.includes(i)) { newObj[i] = obj[i]; } } return newObj; }