3
votes

Objet JSON non-tableau de filtre Javascript

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


3 commentaires

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


7 Réponses :


1
votes

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 )


2 commentaires

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.



2
votes

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)


0 commentaires

0
votes

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


0 commentaires

4
votes

Vous pouvez utiliser Object .fromEntries pour reconstruire l'objet à partir d'entrées filtrées

Voici l'idée: -

  • Commencez par récupérer les entrées de l'objet modèle
  • Filtrer les entrées en fonction de la valeur du filtre
  • Utilisez Object.fromEntries pour créer un objet à partir d'entrées filtrées

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


7 commentaires

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



-1
votes

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)


0 commentaires

-1
votes

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.


0 commentaires

0
votes

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


4 commentaires

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