2010-02-24 47 views
30

我有一个Foo类,有几个成员变量。当这个类的两个实例中的所有值都相等时,我希望这些对象“相等”。然后我会喜欢这些对象作为我的哈希键。当我现在尝试这样做时,哈希将每个实例视为不等。如何在Ruby中使对象实例成为散列键?

h = {} 
f1 = Foo.new(a,b) 
f2 = Foo.new(a,b) 

f1和f2在此处应该相等。

h[f1] = 7 
h[f2] = 8 
puts h[f1] 

应打印8

回答

54

http://ruby-doc.org/core/classes/Hash.html

哈希使用key.eql?测试 等号的密钥。如果您需要使用您自己的类的实例 作为哈希密钥, ,建议您同时定义 eql?和散列方法。散列 方法必须具有以下属性: a.eql?(b)意味着a.hash == b.hash。

eql?方法很容易实现:如果所有成员变量相同,则返回true。对于散列方法,请使用[@ data1,@ data2] .hash,如Marc-Andre在评论中所示。

+0

完美的解释。 =) – Mereghost 2010-02-24 19:23:42

+8

好,除了返回的散列应该是fixnum,所以最好使用exclusive或sum而不是sum(可能溢出到bignum)。或者,使用'Array#hash',比如'[@ data1,@ data2] .hash',说。 – 2010-02-24 20:56:03

+0

好点。将单个哈希加在一起也有可能由不同的单独哈希产生相同的总和(3 + 2 = 5和1 + 4 = 5)。如Marc-Andre所示,使用Array#hash可以使解决方案更加完整。 – Mark 2010-02-24 21:21:37

-3

添加一个名为“散列”的方法到类:

class Foo 
    def hash 
    return whatever_munge_of_instance_variables_you_like 
    end 
end 

这工作,你所要求的方式,不会产生不同,但相同的,不同的对象哈希键。

+4

您还应该以与散列方法一致的方式定义eql?方法,并且散列方法必须返回一个Fixnum,否则它会打破uniq。 – ChrisPhoenix 2013-09-09 13:26:19