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