Comment puis-je obtenir l'intersection, l'union et le sous-ensemble de tableaux dans Ruby?

170

Je souhaite créer différentes méthodes pour une classe appelée Multiset .

J'ai toutes les méthodes requises, mais je ne sais pas comment écrire des méthodes d'intersection, d'union et de sous-ensemble.

Pour l'intersection et l'union, mon code commence comme ceci:

def intersect(var)
  x = Multiset.new
end

Voici un exemple:

X = [1, 1, 2, 4]
Y = [1, 2, 2, 2]

puis l'intersection de Xet Yest [1, 2].

user487743
la source
Le lien de @ Krule est rompu mais je crois qu'il vous a pointé vers la méthode Array "&" qui fait l'intersection, voyez quelques-unes des réponses ici.
rogerdpack
Cela a été répondu il y a plus de 8 ans. Oui, c'était intersection, ruby-doc.org/core-2.6.3/Array.html#method-i-26
Krule

Réponses:

151

En utilisant le fait que vous pouvez effectuer des opérations de définition sur des tableaux en faisant &(intersection), -(différence) et |(union).

Évidemment, je n'ai pas implémenté le MultiSet selon les spécifications, mais cela devrait vous aider à démarrer:

class MultiSet
  attr_accessor :set
  def initialize(set)
    @set = set
  end
  # intersection
  def &(other)
    @set & other.set
  end
  # difference
  def -(other)
    @set - other.set
  end
  # union
  def |(other)
    @set | other.set
  end
end

x = MultiSet.new([1,1,2,2,3,4,5,6])
y = MultiSet.new([1,3,5,6])

p x - y # [2,2,4]
p x & y # [1,3,5,6]
p x | y # [1,2,3,4,5,6]
Mike Lewis
la source
8
2 grands crimes dans cette réponse: (1) Le mot setcomme nom de variable d'un tableau simple; (2) Reproduire tout ce qui fait Arraydéjà. Si l'OP souhaite ajouter des fonctionnalités à la Arrayclasse avec des méthodes supplémentaires, vous devez simplement faire: class MultiSet < Array def inclusion?(other) Set.new(self).subset?(Set.new(other)) end end
Rahul Murmuria
1
D'accord ... c'est probablement le cours le plus inutile que j'ai vu de ma vie ... mais je me rends compte que ce n'est pas vraiment ta faute.
mpowered
313

Je suppose Xet Ysont des tableaux? Si tel est le cas, il existe un moyen très simple de le faire:

x = [1, 1, 2, 4]
y = [1, 2, 2, 2]

# intersection
x & y            # => [1, 2]

# union
x | y            # => [1, 2, 4]

# difference
x - y            # => [4]

La source

Jon Gauthier
la source
17
En d'autres termes, faites-le Multiset < Array.
sawa
Que faire si vous avez x = [1,1,2,4] y = [1,2,2,2] z = [4] Comment pouvez-vous obtenir qu'il vous donne des intersections entre les ensembles au lieu de l'intersection de tous ensembles? Donc au lieu de vous donner [], cela vous donne [1,2,4]?
mharris7190
1
@ mharris7190 vous pouvez prendre l'union de toutes ces intersections:(x & y) | (y & z) | (x & z)
xavdid
2
N'oubliez pas qu'il y en a aussi &=, |=et -=si vous voulez aussi stocker immédiatement la valeur comme je l'ai fait! :)
Pysis
2
Exactement ce que je pensais @sawa. Pourquoi l'OP crée-t-il cette classe en premier lieu? Il ne fait rien que Array ne fasse déjà à partir de Ruby's Standard Lib.
danielricecodes
6

Si Multisets'étend de la Arrayclasse

x = [1, 1, 2, 4, 7]
y = [1, 2, 2, 2]
z = [1, 1, 3, 7]

SYNDICAT

x.union(y)           # => [1, 2, 4, 7]      (ONLY IN RUBY 2.6)
x.union(y, z)        # => [1, 2, 4, 7, 3]   (ONLY IN RUBY 2.6)
x | y                # => [1, 2, 4, 7]

DIFFÉRENCE

x.difference(y)      # => [4, 7] (ONLY IN RUBY 2.6)
x.difference(y, z)   # => [4] (ONLY IN RUBY 2.6)
x - y                # => [4, 7]

INTERSECTION

x & y                # => [1, 2]

Pour plus d'informations sur les nouvelles méthodes de Ruby 2.6, vous pouvez consulter ce billet de blog sur ses nouvelles fonctionnalités

Ana María Martínez Gómez
la source