2011-07-08 9 views
4

私はちょうどそれがこれを読んでいる人には明らかになるように、私が試した簡単な例を下に貼り付けられます。ルビー:ハッシュのプロパティキー

irb(main):001:0> h = { } 
=> {} 
irb(main):002:0> a=[1,2,3] 
=> [1, 2, 3] 
irb(main):003:0> a.object_id 
=> 69922343540500 


irb(main):004:0> h[a] = 12   #Hash with the array as a key 
=> 12 
irb(main):005:0> a << 4    #Modified the array 
=> [1, 2, 3, 4] 
irb(main):006:0> a.object_id  #Object id obviously remains the same. 
=> 69922343540500 
irb(main):007:0> h[a]    #Hash with the same object_id now returns nil. 
=> nil 
irb(main):008:0> h     #Modified hash 
=> {[1, 2, 3, 4]=>12} 
irb(main):009:0> h[[1,2,3,4]]  #Tried to access the value with the modified key - 
=> nil 


irb(main):011:0> h.each { |key,value| puts "#{key.inspect} maps #{value}" } 
[1, 2, 3, 4] maps 12 
=> {[1, 2, 3, 4]=>12} 

ハッシュを繰り返し実行すると、キーと値の間のマップを識別できます。

いくつかのいずれかが私にルビーのハッシュのこの動作を説明してくださいとハッシュキーのプロパティがどのようなものでした。

1)iは、上述のように、OBJECT_IDは変更されていない - なぜゼロに設定された値です。 Hは[1,2,3,4]戻すゼロ上述したようので、私はハッシュ「H」から値「12」を取り戻すことができるように

2)は、任意の可能な方法があります。

答えて

1

ハッシュキーは#eql?メソッドでチェックされ、[1, 2, 3].eql?[1, 2, 3,4]ではないため、ハッシュ検索の結果が異なります。

セマンティクスが機能しない場合はHashキーとしてArray以外のものを使用したいことがありますか?

1

ruby hash apiは答えを提供します:キーは、キーとして使用中に値が変更されるべきではありません

インターンは、aのハッシュが計算され、クイックルックアップに使用されると考えられます(キーは変更しないでください。ハッシュは常に同じです)。したがって、h[a]を実行すると一致するものが見つかりません([1,2,3] .hash!= [1,2,3,4] .hash)、h[[1,2,3]]を実行するとハッシュは一致しますが、オブジェクトは一致しませんマッチ([1,2,3]!= [1,2,3,4])。

修正が、それは変化しないためのキーとしてOBJECT_IDを使用することで、h[a.object_id] = 12は12時に変更を返します。

Rubyはオブジェクトをハッシュするオブジェクト#ハッシュ方式を使用しています。勿論これはh[[1,2,3].object_id]が12

1

Stefaanコールマンの答えは、より徹底しているが、観測のカップルを返さないという欠点を持っています

この時点でa.delete(4); h[a]を実行すると、[1,2,3]をもう一度キーとして使用することができます。

8

それが使用されている間、キーはその値を変更してはならないので、これが起こります。値が変更された場合、現在の値に基づいてハッシュを再構築する必要があります。 rehashの方法についてはRuby APIを見てください。キーが変更された後、ハッシュを再構築することで値を取得することができます。

irb(main):022:0> h.rehash 
=> {[1, 2, 3, 4]=>12} 
irb(main):023:0> h[a] 
=> 12 
関連する問題