Quelle est la meilleure façon de filtrer un objet de cette façon dans ES6?
Données de départ:
const acceptedValues = ["value1","value3"]
const myObject = {
prop1:"value1",
prop2:"value2",
prop3:"value3"
}
Production attendue:
filteredObject = {
prop1:"value1",
prop3:"value3"
}
Vous pouvez utiliser reduce()
pour créer un nouvel objet et includes()
pour vérifier si la valeur de l'objet existe dans le tableau.
const acceptedValues = ["value1", "value3"]
const myObject = {
prop1: "value1",
prop2: "value2",
prop3: "value3"
}
var filteredObject = Object.keys(myObject).reduce(function(r, e) {
if (acceptedValues.includes(myObject[e])) r[e] = myObject[e]
return r;
}, {})
console.log(filteredObject)
Juste pour construire au-dessus de @Nenad Vracar bonne réponse, vous pouvez utiliser un objet au lieu du tableau avec includes
pour une recherche plus rapide:
const acceptedValues = ["value1", "value3"];
const myObject = {
prop1: "value1",
prop2: "value2",
prop3: "value3"
};
const lookup = acceptedValues.reduce( (memo, prop) => {
memo[prop] = true;
return memo;
});
const filteredObject = Object.keys(myObject).reduce((filtered, key) => {
if(lookup[myObject[key]]){
filtered[key] = myObject[key];
}
return filtered;
}, {});
console.log(filteredObject);
Ni que le includes
ne fait pas le travail, mais j'ai pensé à fournir une vue alternative.
Pourquoi pas une simple boucle for?
const acceptedValues = ["value1","value3"]
const myObject = {
prop1:"value1",
prop2:"value2",
prop3:"value3"
};
var filteredObject = {};
for(e in myObject) {
if (myObject.hasOwnProperty(e)) {
if (acceptedValues.indexOf(myObject[e]) != -1) {
filteredObject[e] = myObject[e];
}
}
}
console.log(filteredObject);
Si vous avez besoin d'un code statique ES6 clair (vous savez exactement quelles propriétés vous devez filtrer) et que cela ne dépend pas de l'état de l'application, vous pouvez utiliser la notation de distraction suivante:
const myObject = {
prop1: 'value1',
prop2: 'value2',
prop3: 'value3'
}
const { prop2, ...filteredObject } = myObject
console.info({ filteredObject, prop2 })
Et vous aurez:
prop2 === "value2"
filteredObject === {prop1: "value1", prop3: "value3"}
OMI, la "meilleure façon" est la voie Lodash
const filtered = _.pick(myObject, acceptedValues)
Comme je n'ai pas vu de réponse en utilisant Object.entries
En voici une. Remarque, en raison de l'implémentation de Object.entries()
étant beaucoup plus lente que Object.keys()
, cela sera également plus lent que la réponse acceptée, mais certains peuvent préférer cela pour la lisibilité ou l'extensibilité (plus facile de passer un filtrage différent fonction).
const acceptedValues = ["value1", "value3"];
const myObject = {
prop1:"value1",
prop2:"value2",
prop3:"value3"
};
const filteredEntries = Object.entries(myObject).filter(([, v]) => acceptedValues.includes(v));
const filteredObject = Object.fromEntries(filteredEntries);
Ou en une seule ligne longue:
const filteredObject = Object.fromEntries(Object.entries(myObject).filter(([, v]) => accepted.includes(v)));
Utiliser une boucle for simple et obtenir un objet par clé.
const acceptedValues = ["value1","value3"]
const myObject = {
prop1:"value1",
prop2:"value2",
prop3:"value3"
}
Object.prototype.getKeyByValue = function( value ) {
for( var prop in this ) {
if( this.hasOwnProperty( prop ) ) {
if( this[ prop ] === value )
return prop;
}
}
}
for (var i in acceptedValues) {
if (myObject.getKeyByValue(acceptedValues[i])){
console.log(acceptedValues[i]);
}
}
function filter(myObject){
var obj=Object.assign({},myObject);
Object.keys(obj).forEach(function(key) {
if(acceptedValues.indexOf(obj[key])<0) delete obj[key];
});
return obj;
}
const filteredObject=filter(myObject);