J'essaie de filtrer les objets JSON sans tableau comme l'extrait suivant
{ "two": { "title": "two" }, "three": { "title": "three" } }
Mais ce n'est pas du filtrage
Je reçois la sortie suivante
[ { "one": { "title": "one" }, "two": { "title": "two" }, "three": { "title": "three" } } ]
Sortie désirée
const filter = { filterRows: ['one'] }; const templateMapper = { 'one': { title: 'one', }, 'two': { title: 'two', }, 'three': { title: 'three', }, } const filterDialogView = filter.filterRows; const filterTemplateMapper = [templateMapper].filter(row => !filterDialogView.includes(row)); console.log(filterTemplateMapper);
7 Réponses :
Une option consiste à créer une copie de l'objet templateMapper
, puis à parcourir les filterRows
et à supprimer chaque clé associée:
const filter = { filterRows: ['one'] }; const templateMapper = { 'one': { title: 'one', }, 'two': { title: 'two', }, 'three': { title: 'three', }, }; const filterTemplateMapper = { ...templateMapper }; filter.filterRows.forEach((key) => { delete filterTemplateMapper[key]; }); console.log(filterTemplateMapper);
(également, comme remarques dans les commentaires, Un "objet JSON" n'existe pas )
Cela mute l'objet plutôt que d'en créer un nouveau, ce qui est différent du fonctionnement de la méthode de filtrage.
Il ne modifie pas l'objet d'origine - le {... templateMapper}
crée une copie.
Vous pouvez filtrer
les entrées
de l'objet en premier. Puis utilisez Object.fromEntries ()
pour créer un nouvel objet à partir de ces entrées filtrées.
const filter = { filterRows: ['one'] }; const templateMapper = { 'one': { title: 'one', }, 'two': { title: 'two', }, 'three': { title: 'three', }, } const filteredObject = Object.fromEntries( Object.entries(templateMapper).filter(([k]) => !filter.filterRows.includes(k)) ) console.log(filteredObject)
Vous pouvez filtrer ()
les objets. Vous devez filtrer ()
les entrées de l'objet, puis le convertir à nouveau en objet en utilisant Object.fromEntries()
const filter = { filterRows: ['one'] }; const templateMapper = { 'one': { title: 'one', }, 'two': { title: 'two', }, 'three': { title: 'three', }, } const filterDialogView = filter.filterRows; const filterTemplateMapper = Object.entries(templateMapper) .filter(row =>!filterDialogView.includes(row[0].title)) .reduce((ac,[k,v]) => (ac[k] = v,ac),{}); console.log(filterTemplateMapper);
Si Object.fromEntries ()
n'est pas pris en charge par votre navigateur, utilisez reduce()
const filter = { filterRows: ['one'] }; const templateMapper = { 'one': { title: 'one', }, 'two': { title: 'two', }, 'three': { title: 'three', }, } const filterDialogView = filter.filterRows; const filterTemplateMapper = Object.fromEntries( Object.entries(templateMapper) .filter(row => !filterDialogView.includes(row[0].title)) ); console.log(filterTemplateMapper);
Vous pouvez utiliser Object .fromEntries pour reconstruire l'objet à partir d'entrées filtrées
Voici l'idée: -
const filter = { filterRows: ['one'] }; const template = {'one': {title: 'one',},'two': {title: 'two',},'three': {title: 'three',}} const filterDialogView = filter.filterRows; const final = Object.entries(template).filter(([row])=> !filterDialogView.includes(row)) const output = final.reduce((op,[key,value])=>{ op[key] = value return op },{}) console.log(output);
Si votre environnement ne prend pas en charge Object.fromEntries, vous pouvez utiliser ceci
const filter = { filterRows: ['one'] }; const template = {'one': {title: 'one',},'two': {title: 'two',},'three': {title: 'three',}} const filterDialogView = filter.filterRows; const final = Object.entries(template).filter(([row])=> !filterDialogView.includes(row)) console.log(Object.fromEntries(final));
C'est la meilleure réponse (j'allais poster un code identique) - j'ajouterais aussi quelques remarques sur Object.fromEntries
@JaromandaX merci mon pote :) j'ai ajouté une description du code et du lien associé,
@CodeManiac j'obtiens cette erreur Object.fromEntries n'est pas une fonction dans Node.JS
@ user11229655 quelle version du nœud vous utilisez mate?
j'utilise le nœud v10.15.2
@CodeManiac que j'ai essayé dans REPL.it node ver semble être un problème avec la v10.15.2. a également essayé de réagir son bon fonctionnement grâce
@ user11229655 je ne suis pas sûr de la compatibilité avec le nœud, s'il n'est pas compatible avec cette version, vous pouvez ajouter polyfill pour Object.fromEntries
ou vous pouvez utiliser réduire
pour créer un objet
Au lieu de modifier l'objet d'origine, créez-en une copie et supprimez les clés indésirables. Pour supprimer, vous pouvez utiliser le mot-clé delete
. Itéré le tableau filterRows
, puis utiliser delete
pour supprimer les clés de l'objet copié
const filter = { filterRows: ['one'] }; const templateMapper = { 'one': { title: 'one', }, 'two': { title: 'two', }, 'three': { title: 'three' }, } let newObj = JSON.parse(JSON.stringify(templateMapper)); filter.filterRows.forEach(function(item) { if (newObj.hasOwnProperty(item)) { delete newObj[item] } }); console.log(newObj)
La fonction filter ()
n'est disponible que sur les tableaux. Pour obtenir le même comportement avec un objet, vous devez utiliser les entries()
.
const filter = { filterRows: ['one'] } const templateMapper = { 'one': { title: 'one', }, 'two': { title: 'two', }, 'three': { title: 'three', }, } const filteredMapper = Object.entries(templateMapper).reduce((acc, [key, value]) => { // if the key is not in the filtered list, add this entry to the object if (!filter.filterRows.includes(key)) { acc[key] = value } return acc }, {}) // pass in empty object as initial value of accumulator console.log(filteredMapper)
La façon dont cela fonctionne est que nous obtenons d'abord les entrées
(paires clé / valeur) de templateMapper
. Nous prenons ensuite ces entrées et les réduisons
. Une réduction prend plusieurs arguments dont un "accumulateur" qui rassemble les champs que nous voulons conserver. Nous «détruisons» la clé
et la valeur
afin de pouvoir vérifier si la clé est dans la liste de filtres. S'il ne doit pas être filtré, on l'ajoute à l'accumulateur. Nous retournons ensuite l'accumulateur pour la prochaine itération de la réduction. Enfin, nous passons un objet vide comme valeur initiale de l'accumulateur lors de la première itération.
Vous pouvez utiliser cette méthode:
const filter = { filterRows: ['one'] }; const templateMapper = { 'one': { title: 'one', }, 'two': { title: 'two', }, 'three': { title: 'three', }, } // Convert object templateMapper to array with key const keyArrayTemplateMapper = Object.keys(templateMapper); // Filter key array const filterKey = keyArrayTemplateMapper.filter(key => !filter.filterRows.includes(key)); // Using reduce method to return new array const output = filterKey.reduce((obj, key) => { obj[key] = templateMapper[key]; return obj; }, {}); console.log(output);
Toutes les réponses ici sont contre-évaluées sauf une. Essayez d'ajouter une explication du code.
Je ne vois rien de mal avec votre code, la seule chose qui manque est une explication, il est considéré comme une bonne pratique d'ajouter des explications à votre réponse car cela aidera les futurs lecteurs
Je comprends, a ajouté quelques explications. Merci les gars.
@Scofield, vous pouvez créer votre code sous forme d'extrait de code exécutable lire ici , et voici vos récompenses pour une réponse bien détaillée
où est le JSON? tout ce que je vois est un objet ... et les objets ne peuvent pas être filtrés à l'aide de Array.filter car les objets n'ont pas de méthode de filtrage
j'utilise [templateMapper] voir le code ci-dessus j'ai utilisé [] tableaux
Ouais, mais ce tableau a une entrée - l'objet TOUT