Bagaimana saya bisa mendapatkan persimpangan, gabungan, dan subset array di Ruby?

170

Saya ingin membuat metode yang berbeda untuk kelas yang disebut Multiset .

Saya memiliki semua metode yang diperlukan, tetapi saya tidak yakin bagaimana menulis metode persimpangan, penyatuan, dan subset.

Untuk persimpangan dan gabungan, kode saya mulai seperti ini:

def intersect(var)
  x = Multiset.new
end

Berikut ini sebuah contoh:

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

maka persimpangan Xdan Yadalah [1, 2].

pengguna487743
sumber
Tautan @ Krule rusak tetapi saya yakin dia mengarahkan Anda ke metode Array "&" yang melakukan persimpangan, lihat beberapa jawaban di sini.
rogerdpack
Itu dijawab lebih dari 8 tahun yang lalu. Ya, itu persimpangan, ruby-doc.org/core-2.6.3/Array.html#method-i-26
Krule

Jawaban:

151

Memanfaatkan fakta bahwa Anda dapat melakukan operasi set pada array dengan melakukan &(persimpangan), -(perbedaan), dan |(gabungan).

Jelas saya tidak mengimplementasikan MultiSet ke spec, tetapi ini harus Anda mulai:

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
sumber
8
2 kejahatan besar dalam jawaban ini: (1) Kata setsebagai nama variabel array sederhana; (2) Menggandakan semua yang Arraysudah dilakukan. Jika OP ingin menambahkan fungsionalitas ke Arraykelas dengan beberapa metode tambahan, Anda cukup melakukan: class MultiSet < Array def inclusion?(other) Set.new(self).subset?(Set.new(other)) end end
Rahul Murmuria
1
Setuju ... ini mungkin kelas paling tidak berguna yang pernah kulihat dalam hidupku ... tapi aku sadar itu bukan salahmu.
mowered
313

Saya berasumsi Xdan Yapakah array? Jika demikian, ada cara yang sangat sederhana untuk melakukan ini:

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]

Sumber

Jon Gauthier
sumber
17
Dengan kata lain, lakukan saja Multiset < Array.
sawa
Bagaimana jika Anda memiliki x = [1,1,2,4] y = [1,2,2,2] z = [4] Bagaimana Anda bisa mendapatkannya untuk memberi Anda persimpangan antara set dengan alih-alih persimpangan semua set? Jadi alih-alih memberi Anda [], itu memberi Anda [1,2,4]?
mharris7190
1
@ mharris7190 Anda dapat mengambil persatuan dari semua persimpangan:(x & y) | (y & z) | (x & z)
xavdid
2
Jangan lupa ada juga &=,, |=dan -=jika Anda juga ingin segera menyimpan nilai seperti yang saya lakukan! :)
Pysis
2
Persis seperti yang saya pikirkan @sawa. Mengapa OP menciptakan kelas ini di tempat pertama? Itu tidak melakukan apa pun yang Array belum lakukan dari Ruby Standard Lib.
danielricecodes
6

Jika Multisetmeluas dari Arraykelas

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

PERSATUAN

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]

PERBEDAAN

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

PERSIMPANGAN

x & y                # => [1, 2]

Untuk info lebih lanjut tentang metode baru di Ruby 2.6, Anda dapat memeriksa posting blog ini tentang fitur-fiturnya yang baru

Ana María Martínez Gómez
sumber