Vérifier si deux ensembles ont le même contenu (dans n'importe quel ordre)
Je suis en utilisant Ruby 1.8.6 avec des Rails 1.2.3, et la nécessité de déterminer si deux matrices ont les mêmes éléments, indépendamment de si oui ou non ils sont dans le même ordre. L'un des tableaux est la garantie de ne pas contenir de doublons (l'autre pourrait, dans ce cas la réponse est non).
Ma première pensée a été
require 'set'
a.to_set == b.to_set
mais je me demandais si il y avait une plus efficace ou idiomatiques façon de faire.
- double possible de Ruby - N'tableau contient tous les éléments de la matrice B>
- Essayez de tableau.devrait - = ~ another_array case stackoverflow.com/questions/2978922/...
- Vous pourriez avoir sauvé beaucoup de confusion par: 1) indiquant si les éléments des tableaux sont nécessairement sortable; et 2) de fournir un exemple simple pour clarifier ce que vous entendez par "si deux matrices ont les mêmes éléments" (par exemple, ne
[1,2]
et[2,1,1]
ont les mêmes éléments?) - Ruby 2.6 a introduit
difference
qui offre une solution à la fois très rapide et très lisible. Plus d'infos ici.
Vous devez vous connecter pour publier un commentaire.
Cela ne nécessite pas de conversion à définir:
.uniq.sort
alors? En outreuniq
est similaire àto_set
en interne ainsi que des.to_a.sort
uniq
s. En fait j'ai fini la création de l'un des tableaux avec desRange#to_a
, donc je n'avais qu'àsort
l'autre.pour deux matrices A et B:
A et B ont le même contenu, si:
(A-B).blank? and (B-A).blank?
ou vous pouvez vérifier:
((A-B) + (B-A)).blank?
Aussi comme suggéré par @cort3z cette solution als0 fonctionne pour polymorphes tableaux j'.e
::::::::::: MODIFIER :::::::::::::
Comme suggéré dans les commentaires, solution ci-dessus échoue pour les doublons.Bien que, comme pour la question qui n'est même pas nécessaire, puisque la personne n'est pas intéressée par les doublons(il est la conversion de ses tableaux à la vérification et que les masques des doublons et même si vous regardez la accepté de répondre qu'il est à l'aide d'un .uniq opérateur avant de vérifier et que trop de masques doublons.). Mais encore si des doublons vous intéresse ,Juste l'ajout d'une case de nombre de fixer le même(comme par la question d'une seule table peut contenir des doublons). Donc, la solution finale sera:
A.size == B.size and ((A-B) + (B-A)).blank?
A=[1]
etB=[1,1]
, à la fois(A-B)
et(B-A)
sera de retour vide. Voir Array Documentation.a.to_set == b.to_set
et l'on a accepté la réponse est à l'aide dea.uniq.sort == b.uniq.sort
et les deux donnent exactement le même résultat que((A-B) + (B-A)).blank?
pour A=[1] et B=[1,1] d'accord ? Depuis qu'il a juste poser une amélioration par rapport à sa solution originale , ma solution fonctionne toujours 🙂 . d'accord?A = [123, "test", [], some_object, nil]
etB = A#because I am lazy
, puisA.uniq.sort
lèvera une erreur (comparaison de chaînes de caractères et tableaux a échoué).A = [1, 1, 2]
etB = [1, 2, 2]
Vitesse comparsions
sort
's de vitesseto_set
pour commencer à surperformer avec d'assez grands tableaux où O(n logn) serait de commencer à compter plus de l'effort nécessaire pour convertir le tableau d'ensembleLorsque les éléments de
a
etb
sontComparable
,Correction de @mori de la réponse repose sur @steenslag commentaire
a
etb
peuvent être triées.Ruby 2.6+
Ruby introduit
différence
2.6.Cela donne une très rapide, très lisible solution ici, comme suit:
De l'exécution de l'indice de référence:
Espère que ça aide quelqu'un!
Si vous vous attendez à
[:a, :b] != [:a, :a, :b]
to_set
ne fonctionne pas. Vous pouvez utiliser la fréquence à la place:a.sort == b.sort
si il se soucie de la fréquence?["", :b].frequency == [:b, ""].frequency #=> true
a.group_by{|i| i} == b.group_by{|i| i}
Si vous connaissez les tableaux sont de longueur égale et ni tableau contient des doublons, alors cela fonctionne aussi:
Explication: la
&
opérateur dans ce cas renvoie une copie de a1 sans tous les éléments ne trouve pas dans a2, qui est le même que l'original a1 iff deux tableaux ont le même contenu avec pas de doublons.Analyse: étant Donné que la commande est inchangé, je devine que ce est implémenté sous la forme d'un double itération de manière cohérente
O(n*n)
, notamment pis pour les grands tableaux dea1.sort == a2.sort
qui doit effectuer avec le pire des casO(n*logn)
.a1 = [1,2,3], a2 = [2, 1, 3]
a1 && a2
retourne[2,1,3]
pour moi qui n'est pas égal àa1
a1==a2
? Il peut fonctionner siarray1
sur le côté droit de l'égalité est remplacé pararray2
, mais je doute que l'ordre des éléments retournés par&
est garanti.&&
est logique ET qu'ils sont très différents!Une approche consiste à parcourir le tableau avec pas de doublons
Cette fonction retourne un tableau de trues. Si tout faux s'affiche, puis l'extérieur
include?
retournera true. Ainsi, vous devez inverser le tout afin de déterminer si c'est un match.combinant
&
etsize
peut être trop rapide.