Je récupère des données à partir d'une API qui, parfois, me donne plusieurs objets avec les mêmes valeurs, ou des valeurs très similaires, que je souhaite supprimer.
Par exemple, je pourrais récupérer:
XXX
Je veux donc vérifier que deux objets n'ont pas de clé avec la même valeur "Language" (dans ce cas, "English").
Je voudrais obtenez le processus général de filtrage de l'objet entier si sa valeur "Langue" est dupliquée, avec le problème supplémentaire de ne pas avoir le même nombre d'objets renvoyés à chaque fois. Donc, en autorisant le nombre dynamique d'objets dans le tableau.
Il y a un exemple ici: Résultat inattendu lors du filtrage d'un tableau d'objets par rapport deux autres tableaux d'objets
mais cela suppose que vous avez un nombre défini d'objets dans le tableau et que vous ne comparez que le contenu de ces mêmes objets à chaque fois.
Je chercherais un moyen de comparer
arrayName[eachObject].Language === "English"
et de conserver l'un des objets, mais tous les autres (un nombre inconnu d'objets) devraient être filtrés, très probablement en utilisant .filter () avec .map ().
4 Réponses :
Vous pouvez prendre une table de hachage et filtrer le tableau en vérifiant Name et Language.
.as-console-wrapper { max-height: 100% !important; top: 0; }
var array = [{ Name: "blah", Date: "1992-02-18T00:00:00.000Z", Language: "English" }, { Name: "blahzay", Date: "1998-02-18T00:00:00.000Z", Language: "French" }, { Name: "blah", Date: "1999-02-18T00:00:00.000Z", Language: "English" }],
hash = {},
result = array.filter(({ Name, Language }) => {
var key = `${Name}|${Language}`;
if (!hash[key]) return hash[key] = true;
});
console.log(result);
Les extraits ci-dessous stockent les langues rencontrées dans un tableau. Si le langage des objets en cours est dans le tableau, il est filtré. Il suppose que le premier objet rencontré avec la langue est stocké.
const objs = [
{
"Name": "blah",
"Date": "1992-02-18T00:00:00.000Z",
"Language": "English",
},
{
"Name": "blahzay",
"Date": "1998-02-18T00:00:00.000Z",
"Language": "French",
}, {
"Name": "blah", // same name, no problem
"Date": "1999-02-18T00:00:00.000Z", // different date
"Language": "English", // but same language
},
],
presentLanguages = [];
let languageIsNotPresent;
const objsFilteredByLanguage = objs.filter(function (o) {
languageIsNotPresent = presentLanguages.indexOf(o.Language) == -1;
presentLanguages.push(o.Language);
return languageIsNotPresent;
});
console.log(objsFilteredByLanguage);
J'aime ça mais j'ai du mal à comprendre ce qui se passe. Donc, il parcourt les objets du tableau ("(o)") et pour chacun, vérifie s'il est dans le tableau (languageIsNotPresent est soit vrai soit faux) puis, peu importe si la valeur est vraie ou fausse, en l'ajoutant au presentLanguages, puis renvoyant true ou false pour terminer la boucle. Le retour final annule-t-il l'ajout précédent au tableau?
Dans ce cas, presentLanguages fournit le filtre, car la demande est de ne laisser passer qu'un seul objet par langue. le js Array.filter prend une valeur de retour booléenne. Si c'est vrai, l'élément est présent dans le tableau filtré final si c'est faux, alors ce n'est pas le cas. Ainsi, en utilisant indexOf == -1, nous ne retournons true que si le languageIsNotPresent et cet élément sont ajoutés à notre tableau final. Ainsi, le retour n'annule pas l'ajout précédent car il s'agit de 2 tableaux séparés. 1 faisant office de filtre et l'autre de produit filtré final.
Merci. C'est une très belle fonction succincte.
J'utiliserais le module de soulignement pour JavaScript et la fonction unique dans ce scénario. Voici un exemple de tableau d'objets de données:
const result = _.unique(data, 'language');
Ensuite, nous pouvons utiliser la fonction unique dans la bibliothèque de soulignement pour ne renvoyer qu'une copie des données qui ont des valeurs uniques associées à la clé de langue:
let data = [{
name: 'blah',
date: Date.now(),
language: "en"
},
{
name: 'noblah',
date: Date.now(),
language: 'es'
},
{
name: 'blah',
date: Date.now(),
language: 'en'
}];
Cette réponse renvoie le résultat recherché par l'OP, donc quelqu'un devra expliquer ce vote défavorable. C'est déroutant. Je souhaiterais à quiconque d'exécuter ce code et de le tester lui-même.
je suppose que le vote négatif découle de 2 choses: 1) la dépendance à une bibliothèque au lieu de vanilla js lorsque l'op n'a pas spécifié un désir pour cette bibliothèque 2) vous n'avez pas utilisé l'exemple de données que l'op a fourni pour votre réponse. Cependant, je suis d'accord qu'un vote défavorable sans explication est frustrant.
L'utilisation de Set facilite la suppression des doublons pour autant de clés que vous le souhaitez. J'ai essayé d'être aussi verbeux que possible pour que chaque étape soit claire.
var objects = [{ "Name": "blah", "Date": "1992-02-18T00:00:00.000Z", "Language": "English", }, { "Name": "blah", "Date": "1998-02-18T00:00:00.000Z", "Language": "French", }, { "Name": "blah", "Date": "1999-02-18T00:00:00.000Z", "Language": "English" }];
function uniqueKeyVals(objects, key) {
const objVals = objects.map(object => object[key]); // ex. ["English", "French", "English"]
return objects.slice(0, new Set(objVals).size); // ex. { "English", "French" }.size = 2
}
function removeKeyDuplicates(objects, keys) {
keys.forEach(key => objects = uniqueKeyVals(objects, key));
return objects;
}
// can also use uniqueKeyVals(key) directly for just one key
console.log("Unique 'Language': \n", removeKeyDuplicates(objects, ["Language"]));
console.log("Unique ['Language', 'Name']: \n", removeKeyDuplicates(objects, ["Language", "Name"]));
Ça marche. Je vais exécuter quelques tests et voir s'il reste sur ses pieds lors de la récupération d'une variété de données de l'API. Je vais également fouiller avec le code jusqu'à ce que je comprenne complètement ce qui se passe avec chaque fonction.
Dans le cas où les langues se répètent, souhaitez-vous conserver la première ou la deuxième instance?