Як я можу отримати перетин, об'єднання та підмножину масивів у Ruby?


170

Я хочу створити різні методи для класу під назвою Multiset .

У мене є всі необхідні методи, але я не впевнений, як написати методи перетину, з'єднання та підмножини.

Для перетину та об'єднання мій код починається так:

def intersect(var)
  x = Multiset.new
end

Ось приклад:

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

то перетин Xі Yє [1, 2].



@ Посилання Круля розірвано, але я вважаю, що він вказував вам на метод "&" масиву, який перетинає, дивіться деякі відповіді тут.
rogerdpack

На це відповіли більше 8 років тому. Так, це було перехрестя, ruby-doc.org/core-2.6.3/Array.html#method-i-26
Круле

Відповіді:


151

Використовуючи той факт, що ви можете робити встановлені операції над масивами, виконуючи &(перетин), -(різниця) та |(об'єднання).

Очевидно, що я не застосував MultiSet до специфікацій, але це повинно розпочати:

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]

8
2 великі злочини у цій відповіді: (1) Слово setяк назва змінної простого масиву; (2) Реплікація всього, що Arrayвже є. Якщо ОП хоче додати функціональності до Arrayкласу деякими додатковими методами, вам слід просто зробити: class MultiSet < Array def inclusion?(other) Set.new(self).subset?(Set.new(other)) end end
Рахул Мурмурія,

1
Домовилися ... це, мабуть, найкорисніший клас, який я бачив у своєму житті ... але я розумію, що це насправді не ваша вина.
mpowered

313

Я припускаю, Xчи Yце масиви? Якщо це так, є дуже простий спосіб зробити це:

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]

Джерело


17
Іншими словами, просто робіть Multiset < Array.
sawa

Що робити, якщо у вас x = [1,1,2,4] y = [1,2,2,2] z = [4] Як ви можете домогтися, щоб ви отримали будь-які перетини між наборами замість перетину всіх набори? Отже, замість того, що він дає вам [], він дає вам [1,2,4]?
mharris7190

1
@ mharris7190 ви можете прийняти союз усіх цих перехресть:(x & y) | (y & z) | (x & z)
xavdid

2
Не забувайте , що є також &=, |=і -=якщо ви хочете негайно зберегти значення , як я зробив! :)
Pysis

2
Саме те, що я думав @sawa. Чому ОП створює цей клас в першу чергу? Це не робить нічого, чого Array вже не робить із Standard Lib Ruby.
danielricecodes

6

Якщо Multisetпоходить від Arrayкласу

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

СОЮЗ

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]

РІЗНАННЯ

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

ПІДТРИМКА

x & y                # => [1, 2]

Для отримання додаткової інформації про нові методи в Ruby 2.6, ви можете ознайомитись у цій публікації в блозі про її нові функції

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.