Filtrer les propriétés de l’object par clé dans ES6

Disons que j’ai un object:

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

Je veux créer un autre object en filtrant l’object ci-dessus, donc j’ai quelque chose comme ça.

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

Je cherche un moyen propre d’accomplir ceci en utilisant Es6, donc les opérateurs de diffusion sont à ma disposition. Merci!

Si vous avez une liste de valeurs autorisées, vous pouvez facilement les conserver dans un object en utilisant:

 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); 

Si vous êtes d’accord avec l’utilisation de la syntaxe ES6, je trouve que la façon la plus propre de le faire, comme indiqué ici et ici est la suivante:

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

Maintenant, newData contient:

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

Ou, si vous avez la clé stockée sous forme de chaîne:

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

Dans ce dernier cas, [key] est converti en item2 mais comme vous utilisez une affectation const , vous devez spécifier un nom pour l’affectation. _ représente une valeur de jet.

Plus généralement:

 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 ssortingng to key first, ... 

Non seulement cela réduit-il votre opération à une ligne simple, mais il ne vous oblige pas non plus à connaître les autres clés (celles que vous souhaitez conserver).

La façon la plus propre que vous pouvez trouver est avec 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) 

Rien de ce qui a été dit auparavant, mais pour combiner certaines réponses à une réponse ES6 générale:

 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); 

Vous pouvez append un ofilter générique (implémenté avec oreduce générique) afin de pouvoir facilement filtrer les objects comme vous le pouvez.

 const oreduce = (f, acc, o)=> Object.keys(o).reduce((acc, k)=> f(acc, o[k], k, o), acc) const ofilter = (f, o)=> oreduce ((acc, v, k, o)=> f(v, k, o) ? Object.assign(acc, {[k]: v}) : acc, {}, o) let data = { item1: { key: 'sdfd', value:'sdfd' }, item2: { key: 'sdfd', value:'sdfd' }, item3: { key: 'sdfd', value:'sdfd' } } // filter data where k ("key") is not equal to 'item2' let result = ofilter ((v,k)=> k !== 'item2', data) console.log(result) 

Juste une autre solution que je jouais avec la fonctionnalité “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); 

Voici comment je l’ai fait récemment:

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

Piggybacking sur la réponse de ssube .

Voici une version réutilisable.

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

Pour l’appeler utiliser

 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); 

La beauté des fonctions de flèche ES6 réside dans le fait que vous n’avez pas besoin de transmettre les parameters allowed .

Les réponses ici sont certainement appropriées mais elles sont un peu lentes car elles nécessitent une boucle dans la liste blanche pour chaque propriété de l’object. La solution ci-dessous est beaucoup plus rapide pour les jeux de données volumineux, car elle ne fait que parcourir la liste blanche une seule fois:

 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) 

Vous pouvez faire quelque chose comme ça:

 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); 

Cela fonctionne mais n’est pas très clair, et l’instruction with n’est pas recommandée ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with ).

OK, que diriez-vous de ceci:

 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.toSsortingng()]; } const newObj = {}; for(i in obj) { if(!filter.includes(i)) { newObj[i] = obj[i]; } } return newObj; } 

et appelez comme ceci:

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

Il y a plusieurs façons d’accomplir ceci. La réponse acceptée utilise une approche Keys-Filter-Reduce, qui n’est pas la plus performante.

Au lieu de cela, utiliser une boucle for...in pour parcourir les clés d’un object, ou parcourir les clés autorisées, puis composer un nouvel object est environ 50% plus performant a .

 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 

une. Voir jsPerf pour les benchmarks d’un cas d’utilisation simple. Les résultats seront différents selon les navigateurs.