2010-10-15 41 views
5

Hãy xem xét điều này:đối tượng So sánh trong ruby ​​

class Aaa 
    attr_accessor :a, :b 
end 

x = Aaa.new 
x.a, x.b = 1,2 
y = Aaa.new 
y.a, y.b = 1,2 

puts x == y #=>false 

Có một số cách để kiểm tra xem tất cả các thuộc tính công cộng đều bình đẳng trong các lớp học của cùng loại?

Trả lời

6
class Aaa 
    attr_accessor :a, :b 

    def ==(other) 
    return self.a == other.a && self.b == other.b 
    end 
end 

x = Aaa.new 
x.a,x.b = 1,2 
y = Aaa.new 
y.a,y.b = 1,2 
y = Aaa.new 
y.a,y.b = 1,2 
z = Aaa.new 
z.a,z.b = 1,3 

x == y # => true 
x == z # => false 
+0

Nhưng nếu tôi muốn làm điều này bằng các lớp khác thì sao? Hoặc nếu có 100 thuộc tính? – dfens

+4

Trong phương pháp == (khác) của bạn, bạn có thể thực hiện self.instance_variables.each do | ivar | self.ivar == other.ivar end Bạn cũng có thể xem xét ===. –

+0

đã làm việc cho tôi, cảm ơn – dfens

8
Aaa = Struct.new(:a, :b) 

x = Aaa.new 
x.a, x.b = 1,2 
y = Aaa.new 
y.a, y.b = 1,2 

x == y #=> true 

Struct định nghĩa ==, eql?, và hash cho bạn, vì vậy mà hai Aaa s đều bình đẳng, nếu giá trị của họ cho ab đều bình đẳng. Nó cũng định nghĩa initialize để bạn có thể tùy chọn chuyển các giá trị cho ab khi tạo đối tượng (Aaa.new(value_for_a, value_for_b)). Và nó xác định to_a để trả lại [a,b].

Bạn cũng có thể sử dụng Struct.new với một khối để xác định phương pháp bổ sung, do đó bạn có toàn bộ sức mạnh của một lớp "bình thường":

Aaa = Struct.new(:a, :b) do 
    def c 
    a+b 
    end 
end 
Aaa.new(23,42).C#=> 65 
+0

Điều này có vẻ tốt nhưng tôi cần chức năng này cho các đối tượng, dù sao có phản hồi tốt đẹp tôi không biết về Structs – dfens

+1

@dfens: Đó là những đối tượng. 'Struct.new' chỉ là một phương thức nhà máy cho các lớp. Bạn sẽ có được hành vi giống hệt nhau nếu bạn định nghĩa 'Aaa' bằng từ khóa' class' và sau đó tự định nghĩa '==' v.v. – sepp2k

0

thêm phương pháp để đối phó với việc so sánh đối tượng trong Ruby gồm đang sử dụng hash. Vì lý do hiệu suất, khi lớp là rất lớn, tốt nhất là sử dụng hash để so sánh ruby ​​các đối tượng như vậy:

lớp Aaa attr_accessor: a,: b

def intialize (value_a, value_b) @a = value_a @b = value_b cuối

def băm (target) @ a.hash == target.a.hash & & @ b.hash == target.b.hash cuối cuối

A = mới Aaa ('bất cứ điều gì', 'bất cứ khi nào') B = new Aaa ('tuy nhiên', 'ai') A.hash (B)

1

Chúng ta có thể dễ dàng khái quát đến bất kỳ số lượng các trường hợp và thả các yêu cầu đối với thu khí cho các biến Ví dụ:

class Aaa 
    def initialize(a,b,c) 
    @a, @b, @c = a, b, c 
    end 
end 

x = Aaa.new(1,2,3) 
y = Aaa.new(1,2,3) 
z = Aaa.new(1,2,3) 
arr = [x,y,z] 

x.instance_variables.map do |v| 
    arr.map { |i| i.send(:instance_variable_get,v) }.uniq.size == 1 
end.all? 
    #=>true 

Thay đổi z tới:

z = Aaa.new(1,2,4) 

thì:

x.instance_variables.map do |v| 
    arr.map { |i| i.send(:instance_variable_get,v) }.uniq.size == 1 
end.all? 
    #=> false 
Các vấn đề liên quan