J'ai deux ensembles de résultats comme celui-ci:
// Result 1
[
{ value: "0", display: "Jamsheer" },
{ value: "1", display: "Muhammed" },
{ value: "2", display: "Ravi" },
{ value: "3", display: "Ajmal" },
{ value: "4", display: "Ryan" }
]
// Result 2
[
{ value: "0", display: "Jamsheer" },
{ value: "1", display: "Muhammed" },
{ value: "2", display: "Ravi" },
{ value: "3", display: "Ajmal" },
]
Le résultat final dont j'ai besoin est la différence entre ces tableaux - le résultat final devrait être comme ceci:
[{ value: "4", display: "Ryan" }]
Est-il possible de faire quelque chose comme ça en JavaScript?
Réponses:
En utilisant uniquement JS natif, quelque chose comme ça fonctionnera:
la source
return a.value ===...
dans votre réponse? (Belle solution, au fait, +1) Mis à part l'utilisationArray.prototype.some()
, je ne peux pas vraiment trouver un moyen plus efficace / plus court de le faire.true
ou unefalse
valeur.) Dans ce cas, si nous séparons la notion de test d'égalité du reste du code en demandant à l'utilisateur de passer le contrôle d'égalité en tant que fonction, nous pouvons faire un algorithme générique simple.Vous pouvez utiliser
Array.prototype.filter()
en combinaison avecArray.prototype.some()
.Voici un exemple (en supposant que vos tableaux sont stockés dans les variables
result1
etresult2
):la source
Pour ceux qui aiment les solutions one-liner dans ES6, quelque chose comme ceci:
la source
J'adopte une approche légèrement plus générale, bien que des idées similaires aux approches de @Cerbrus et @Kasper Moerch . Je crée une fonction qui accepte un prédicat pour déterminer si deux objets sont égaux (ici nous ignorons la
$$hashKey
propriété, mais cela pourrait être n'importe quoi) et retourne une fonction qui calcule la différence symétrique de deux listes en fonction de ce prédicat:Il a un avantage mineur sur l'approche de Cerebrus (tout comme l'approche de Kasper Moerch) en ce qu'il s'échappe tôt; s'il trouve une correspondance, il ne prend pas la peine de vérifier le reste de la liste. Si j'avais un
curry
fonction à portée de main, je le ferais un peu différemment, mais cela fonctionne très bien.Explication
Un commentaire demandait une explication plus détaillée pour les débutants. Voici une tentative.
On passe la fonction suivante à
makeSymmDiffFunc
:Cette fonction est la façon dont nous décidons que deux objets sont égaux. Comme toutes les fonctions qui retournent
true
oufalse
, cela peut être appelé une "fonction de prédicat", mais ce n'est que de la terminologie. Le point principal est qu'ilmakeSymmDiffFunc
est configuré avec une fonction qui accepte deux objets et retournetrue
si nous les considérons égaux,false
sinon.En utilisant cela,
makeSymmDiffFunc
(lire "faire une fonction de différence symétrique") nous renvoie une nouvelle fonction:C'est la fonction que nous utiliserons réellement. On lui passe deux listes et il trouve les éléments dans la première pas dans la seconde, puis ceux dans la seconde pas dans la première et on combine ces deux listes.
En y repensant, j'aurais certainement pu s'inspirer de votre code et simplifier un peu la fonction principale en utilisant
some
:complement
utilise le prédicat et renvoie les éléments de sa première liste pas dans sa seconde. C'est plus simple que mon premier passage avec unecontains
fonction séparée .Enfin, la fonction principale est enveloppée dans une expression de fonction immédiatement appelée ( IIFE ) pour garder la
complement
fonction interne hors de la portée globale.Mise à jour, quelques années plus tard
Maintenant que ES2015 est devenu assez omniprésent, je suggère la même technique, avec beaucoup moins de passe-partout:
la source
Cela retournera la différence entre deux tableaux d'objets, en utilisant la clé
value
pour les comparer. Notez que deux choses avec la même valeur ne seront pas retournées, car les autres clés sont ignorées.Ceci fait partie de lodash .
la source
Vous pouvez créer un objet avec des clés comme valeur unique correspondant à chaque objet du tableau, puis filtrer chaque tableau en fonction de l'existence de la clé dans l'objet d'un autre. Cela réduit la complexité de l'opération.
ES6
ES5
la source
Je pense que la solution @Cerbrus est parfaite. J'ai implémenté la même solution mais extrait le code répété dans sa propre fonction (DRY).
la source
J'ai trouvé cette solution en utilisant un filtre et certains.
la source
La plupart des réponses ici sont plutôt complexes, mais la logique derrière cela n'est-elle pas assez simple?
Complexité O (n ^ 2).
la source
vous pouvez faire diff a sur b et diff b sur a, puis fusionner les deux résultats
la source
J'ai fait un diff généralisé qui compare 2 objets de tout type et peut exécuter un gestionnaire de modification gist.github.com/bortunac "diff.js" un exemple d'utilisation:
donc la propriété a est modifiée, b est supprimée, c modifiée, d est ajouté
}
maintenant utiliser comme
la console montrera
la source
La manière la plus générique et la plus simple:
la source
Je préfère les objets cartographiques lorsqu'il s'agit de grands tableaux.
la source
JavaScript a des cartes, qui fournissent le temps d'insertion et de recherche O (1). Par conséquent, cela peut être résolu en O (n) (et non en O (n²) comme le font toutes les autres réponses). Pour cela, il est nécessaire de générer une clé primitive unique (chaîne / numéro) pour chaque objet. On pourrait
JSON.stringify
, mais c'est assez sujet aux erreurs car l'ordre des éléments pourrait influencer l'égalité:Par conséquent, je prendrais un délimiteur qui n'apparaît dans aucune des valeurs et composerais une chaîne manuellement:
Ensuite, une carte est créée. Lorsqu'un élément existe déjà dans la carte, il est supprimé, sinon il est ajouté. Par conséquent, seuls les éléments qui sont inclus les temps impairs (c'est-à-dire une seule fois) restent. Cela ne fonctionnera que si les éléments sont uniques dans chaque tableau:
Afficher l'extrait de code
la source
Je suis tombé sur cette question en cherchant un moyen de choisir le premier élément d'un tableau qui ne correspond à aucune des valeurs d'un autre tableau et j'ai réussi à le trier éventuellement avec array.find () et array.filter () comme ce
si vous devez continuer à chercher une liste mise à jour avant de contre-vérifier la meilleure option suivante, cela devrait fonctionner assez bien :)
la source
Si vous souhaitez utiliser des bibliothèques externes, vous pouvez utiliser _.difference dans le fichier underscore.js pour y parvenir. _.difference renvoie les valeurs du tableau qui ne sont pas présentes dans les autres tableaux.
la source