2010-02-24 72 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