2

重複の可能性:
Hash.new([]) 使用時の Ruby の奇妙な動作

言葉を失ったので、これは簡単なことです。

なぜこうなった:

1.9.3-p194 :001 > h = Hash.new([])
 => {} 
1.9.3-p194 :002 > h[:key1] << "Ruby"
 => ["Ruby"] 
1.9.3-p194 :003 > h
 => {} 
1.9.3-p194 :004 > h.keys
 => [] 
1.9.3-p194 :005 > h[:key1]
 => ["Ruby"] 
4

5 に答える 5

8

次のようなハッシュを作成すると:

h = Hash.new([])       

つまり、まだ定義されていないキーを使用してハッシュにアクセスすると、次の値が返されます。

[]

今あなたがするとき:

h[:key1] << "Ruby"

h[:key1]が返さ[]れ、そこ"Ruby"にプッシュされ["Ruby"]、最後に返されたオブジェクトであるため、出力として が返されます。'h' が未定義のキーでアクセスされたときに返されるデフォルト値としても設定されています。したがって、次の場合:

h[:key1] or h[:key2] or h[:whatever]

あなたは得るでしょう

"Ruby"

出力として。お役に立てれば。

于 2012-10-11T11:48:14.310 に答える
4

Hash.new のドキュメントを見てください

new → new_hash
new(obj) → new_hash
new {|hash, key| block } → new_hash

その後、このハッシュがハッシュ エントリに対応しないキーによってアクセスされた場合、返される値は、ハッシュの作成に使用された new のスタイルによって異なります。

  1. 最初の形式では、アクセスは nil を返します。
  2. obj が指定されている場合、この単一のオブジェクトがすべてのデフォルト値に使用されます。
  3. ブロックが指定されている場合、それはハッシュ オブジェクトとキーで呼び出され、デフォルト値を返す必要があります。必要に応じて、値をハッシュに格納するのはブロックの役割です。

irb(main):015:0> h[:abc] # ["Ruby"]

["Ruby"]キーが見つからない場合、nil の代わりにデフォルト値としてsoが返されます。

于 2012-10-11T11:39:11.167 に答える
2

この構造Hash.new([])はデフォルト値を返しますが、この値はハッシュの初期化された値ではありません。デフォルト値がハッシュの一部であると仮定して、ハッシュを操作しようとしています。

必要なのは、あるキーでハッシュを初期化する構築です。

hash = Hash.new { |h,k| h[k] = [] } 

hash[:key1] << "Ruby"

hash #=> {:key1=>["Ruby"]}
于 2012-10-11T11:37:03.127 に答える
2

実際には で値を設定していませんh[:keys] << "Ruby"。見つからないキーの返されたデフォルト配列の値を追加するだけです。したがって、キーは作成されません。

以下のように書けばOKです。

h = Hash.new([])
h[:keys1] = []
h[:keys1] << "Ruby"
于 2012-10-11T11:40:08.347 に答える
1

私があなたの質問を読んだとき、私もこれが私をつまずかせたことを認めなければなりません。ドキュメントを見てみましたが、明らかになりました。

objが指定されている場合、この単一のオブジェクトがすべてのデフォルト値に使用されます。

つまり、実際に行っているのは、キーに割り当てることなく、デフォルト値に使用されるこの1つの配列オブジェクトを変更することです。

見てみな:

h = Hash.new([])

h[:x] << 'x'
# => ['x']

h
# => {}

h[:y]
# => ['x']  # CRAZY TIMES

だからあなたはどういうわけか割り当てを行う必要があります-h[:x] += ['x']行く方法かもしれません。

于 2012-10-11T11:43:47.710 に答える