Làm cách nào tôi có thể có giao điểm, liên kết và tập hợp con của mảng trong Ruby?


170

Tôi muốn tạo các phương thức khác nhau cho một lớp có tên là Multiset .

Tôi có tất cả các phương thức cần thiết, nhưng tôi không chắc về cách viết các phương thức giao nhau, kết hợp và tập hợp con.

Đối với giao lộ và liên minh, mã của tôi bắt đầu như thế này:

def intersect(var)
  x = Multiset.new
end

Đây là một ví dụ:

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

sau đó là giao điểm của XY[1, 2].



Liên kết của @ Krule bị hỏng nhưng tôi tin rằng anh ta đang chỉ cho bạn phương thức Array "&" giao nhau, xem một số câu trả lời ở đây.
rogerdpack

Điều đó đã được trả lời hơn 8 năm trước. Vâng, đó là giao lộ, ruby-doc.org/core-2.6.3/Array.html#method-i-26
Krule

Câu trả lời:


151

Sử dụng thực tế là bạn có thể thực hiện các thao tác trên mảng bằng cách thực hiện &(giao nhau), -(khác biệt) và| (liên kết).

Rõ ràng là tôi đã không triển khai Multiset để thông số kỹ thuật, nhưng điều này sẽ giúp bạn bắt đầu:

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 tội lớn trong câu trả lời này: (1) Từ setnhư tên biến của một mảng đơn giản; (2) Nhân rộng mọi thứ Arrayđã làm. Nếu OP muốn thêm chức năng cho Arraylớp bằng một số phương thức bổ sung, bạn chỉ cần thực hiện: class MultiSet < Array def inclusion?(other) Set.new(self).subset?(Set.new(other)) end end
Rahul Murmuria

1
Đồng ý ... đây có lẽ là lớp vô dụng nhất tôi từng thấy trong đời ... nhưng tôi nhận ra đó không thực sự là lỗi của bạn.
bắt đầu từ

313

Tôi giả sử XYlà mảng? Nếu vậy, có một cách rất đơn giản để làm điều nà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]

Nguồn


17
Nói cách khác, chỉ cần làm Multiset < Array.
sawa

Điều gì sẽ xảy ra nếu bạn có x = [1,1,2,4] y = [1,2,2,2] z = [4] Làm thế nào bạn có thể lấy nó để cung cấp cho bạn bất kỳ giao điểm nào giữa các bộ thay vì giao điểm của tất cả bộ? Vì vậy, thay vì nó mang lại cho bạn [], nó mang lại cho bạn [1,2,4]?
mharris7190

1
@ mharris7190 bạn có thể kết hợp tất cả các giao lộ đó:(x & y) | (y & z) | (x & z)
xavdid

2
Đừng quên cũng có &=, |=-=nếu bạn cũng muốn lưu trữ ngay giá trị như tôi đã làm! :)
Pysis

2
Chính xác những gì tôi nghĩ @sawa. Tại sao OP tạo ra lớp này ở nơi đầu tiên? Nó không làm bất cứ điều gì mà Array chưa làm từ Standard Lib của Ruby.
danielricecodes

6

Nếu Multisetkéo dài từ Arraylớp học

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

LIÊN HIỆP

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]

SỰ KHÁC BIỆT

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

NGÃ TƯ

x & y                # => [1, 2]

Để biết thêm thông tin về các phương thức mới trong Ruby 2.6, bạn có thể kiểm tra bài đăng trên blog này về các tính năng mới của nó

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.