Comment comparer deux ensembles javascript? J'ai essayé d'utiliser ==
et ===
mais les deux renvoient false.
a = new Set([1,2,3]);
b = new Set([1,3,2]);
a == b; //=> false
a === b; //=> false
Ces deux ensembles sont équivalents, car par définition, les ensembles n'ont pas d'ordre (du moins pas généralement). J'ai regardé la documentation de Set on MDN et je n'ai rien trouvé d'utile. Quelqu'un sait-il comment faire ça?
javascript
set
ecmascript-6
williamcodes
la source
la source
===
est pour l'égalité des valeurs, pas l'égalité des objets.new Set([1,2,3]) != new Set([1,2,3])
. Cela rend l' ensemble Javascript inutile pour les ensembles d'ensembles car le sur-ensemble contiendra des sous-ensembles en double. La seule solution de contournement qui me vient à l'esprit consiste à convertir tous les sous-ensembles en tableaux, à trier chaque tableau, puis à encoder chaque tableau sous forme de chaîne (par exemple JSON).Réponses:
Essaye ça:
Une approche plus fonctionnelle serait:
La
all
fonction fonctionne pour tous les objets itérables (par exempleSet
etMap
).Si elle
Array.from
était plus largement prise en charge, nous aurions pu implémenter laall
fonction comme suit:J'espère que cela pourra aider.
la source
has
enisPartOf
ouisIn
ouelem
Vous pouvez également essayer:
la source
lodash fournit
_.isEqual()
, qui fait des comparaisons approfondies. Ceci est très pratique si vous ne voulez pas écrire le vôtre. À partir de lodash 4,_.isEqual()
compare correctement les ensembles.la source
L'autre réponse fonctionnera bien; voici une autre alternative.
Cependant, sachez que cela ne fait pas de comparaison d'égalité profonde. Alors
retournera faux. Si les deux ensembles ci-dessus doivent être considérés comme égaux, nous devons parcourir les deux ensembles en effectuant des comparaisons de qualité approfondies sur chaque élément. Nous stipulons l'existence d'une
deepEqual
routine. Alors la logique seraitCe que cela fait: pour chaque membre de s1, recherchez un membre profondément égal de s2. S'il est trouvé, supprimez-le afin qu'il ne puisse plus être utilisé. Les deux ensembles sont profondément égaux si tous les éléments de s1 se trouvent dans s2 et si s2 est épuisé. Non testé.
Cela peut vous être utile: http://www.2ality.com/2015/01/es6-set-operations.html .
la source
Aucune de ces solutions ne «ramène» la fonctionnalité attendue à une structure de données telle qu'un ensemble d'ensembles. Dans son état actuel, l' ensemble Javascript est inutile à cette fin car le sur-ensemble contiendra des sous-ensembles dupliqués, que Javascript considère à tort comme distincts. La seule solution à laquelle je peux penser est de convertir chaque sous-ensemble en Array , de le trier puis de l'encoder en String (par exemple JSON).
Solution
Utilisation de base
Test ultime: ensemble d'ensembles
la source
[...set1].sort().toString() === [...set2].sort().toString()
La raison pour laquelle votre approche retourne false est que vous comparez deux objets différents (même s'ils ont le même contenu), comparant ainsi deux objets différents (pas des références, mais des objets) vous renvoie toujours faux.
L'approche suivante fusionne deux ensembles en un seul et compare stupidement la taille. Si c'est pareil, c'est pareil:
À l'envers : C'est très simple et court. Pas de bibliothèque externe uniquement vanilla JS
Inconvénient : cela va probablement être plus lent qu'une simple itération sur les valeurs et vous avez besoin de plus d'espace.
la source
Comparaison de deux objets avec ==, ===
Lorsque vous utilisez l' opérateur
==
ou===
pour comparer deux objets, vous obtiendrez toujours àfalse
moins que ces objets ne font référence au même objet . Par exemple:Sinon, == équivaut à false même si l'objet contient les mêmes valeurs:
Vous devrez peut-être envisager une comparaison manuelle
Dans ECMAScript 6, vous pouvez convertir au préalable des ensembles en tableaux afin de pouvoir repérer la différence entre eux:
REMARQUE:
Array.from
est l'une des fonctionnalités standard d'ECMAScript 6, mais elle n'est pas largement prise en charge dans les navigateurs modernes. Vérifiez le tableau de compatibilité ici: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#Browser_compatibilityla source
b
dont ne sont pas membresa
?b
sont absentsa
est de vérifier sia.size === b.size
.a.size === b.size
abord à court-circuiter la comparaison des éléments individuels si ce n'est pas nécessaire?has
opération sur les ensembles est conçue pour être très efficace, contrairement à l'indexOf
opération sur les tableaux. Par conséquent, il serait logique de changer votre fonction de filtre pour qu'elle soitreturn !b.has(i)
. Cela éliminerait également le besoin de convertirb
en un tableau.J'ai créé un polyfill rapide pour Set.prototype.isEqual ()
Github Gist - Set.prototype.isEqual
la source
Sur la base de la réponse acceptée, en supposant le soutien de
Array.from
, voici une ligne unique:la source
eqSet = (a,b) => a.size === b.size && [...a].every(b.has.bind(b))
Si les ensembles ne contiennent que des types de données primitifs ou si les objets à l'intérieur des ensembles ont une égalité de référence, il existe un moyen plus simple
const isEqualSets = (set1, set2) => (set1.size === set2.size) && (set1.size === new Set([...set1, ...set2]).size);
la source
Je suis cette approche dans les tests:
la source
a=[1,2,3]
etb=[1,2,3,4]
, alors cela dit qu'ils sont les mêmes. Donc, je suppose que vous avez besoin d'une vérification supplémentaire commesetA.size === setB.size
Très légère modification basée sur la réponse de @Aadit M Shah:
Si quelqu'un d'autre a un problème comme moi en raison d'une bizarrerie de la dernière babel, il fallait ajouter un conditionnel explicite ici.
(Aussi pour le pluriel, je pense que
are
c'est juste un peu plus intuitif à lire à haute voix 🙃)la source
1) Vérifiez si les tailles sont égales. Sinon, ils ne sont pas égaux.
2) itérer sur chaque élément de A et archiver qui existe dans B.Si l'un échoue, retournez
unequal
3) Si les 2 conditions ci-dessus échouent, cela signifie qu'elles sont égales.
2) Méthode 2
la source
forEach
méthode ne rendra PAS la fonction parent de retour.