这是一个简单的,因为我失去了言语。
为什么会这样:
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"]
这是一个简单的,因为我失去了言语。
为什么会这样:
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"]
当您创建这样的哈希时:
h = Hash.new([])
这意味着,每当使用尚未定义的键访问哈希时,它都会返回:
[]
现在当你这样做时:
h[:key1] << "Ruby"
h[:key1]
已返回[]
,"Ruby"
被推送到其中,导致["Ruby"]
, 作为输出,因为这是返回的最后一个对象。这也被设置为使用未定义键访问“h”时返回的默认值。因此,当您这样做时:
h[:key1] or h[:key2] or h[:whatever]
你会得到
"Ruby"
作为输出。希望这可以帮助。
查看 Hash.new 的文档
new → new_hash
new(obj) → new_hash
new {|hash, key| block } → new_hash
如果此哈希随后被不对应于哈希条目的键访问,则返回的值取决于用于创建哈希的 new 的样式。
irb(main):015:0> h[:abc] # ["Ruby"]
["Ruby"]
如果未找到键,则返回默认值而不是 nil 。
此构造Hash.new([])
返回默认值,但该值不是哈希的初始化值。您正在尝试使用哈希,假设默认值是哈希的一部分。
您需要的是在某个键处初始化散列的构造:
hash = Hash.new { |h,k| h[k] = [] }
hash[:key1] << "Ruby"
hash #=> {:key1=>["Ruby"]}
您实际上没有使用 设置值h[:keys] << "Ruby"
。您只需为返回的未找到键的默认数组添加一个值。所以没有创建密钥。
如果你写这个,那就没问题了:
h = Hash.new([])
h[:keys1] = []
h[:keys1] << "Ruby"
我不得不承认,当我阅读您的问题时,这也让我感到困惑。我看了一下文档,但它变得很清楚。
如果指定了obj,则此单个对象将用于所有默认值。
因此,您实际上所做的是修改这个用于默认值的单个数组对象,而无需分配给键!
看看这个:
h = Hash.new([])
h[:x] << 'x'
# => ['x']
h
# => {}
h[:y]
# => ['x'] # CRAZY TIMES
因此,您需要以某种方式进行分配-h[:x] += ['x']
可能是要走的路。