这个哈希是怎么回事?

时间:2015-06-17 10:00:33

标签: ruby hash

  1. 我使用默认值为空数组创建一个新哈希。

    h = Hash.new([])
    
  2. 我将值推入密钥为'a'的哈希值。

    h['a'].push(1243)
    
  3. h为空。

    h # => {} 
    
  4. h['a']返回预期值。

    h['a'] # => [1243] 
    
  5. h.keys返回一个空数组。

    h.keys # => []
    
  6. 如果我使用Hash.new {|h,k| h[k]=[]}初始化第一步中的哈希值,则返回预期值。

4 个答案:

答案 0 :(得分:4)

请注意,与块不同,所有参数仅在方法调用之前计算一次。

  • 在步骤1中,您将指定特定数组作为默认值。此数组实例将用于默认值h。请注意,由于您尚未使用块设置默认值,因此调用键值对不会将其分配给哈希值。
  • 在步骤2中,调用默认值的数组实例,因为'a'不是哈希的键。您正在修改此数组实例。
  • 步骤3和5是一回事;由于您没有为块分配默认值h,因此调用的键值对未分配给哈希值。
  • 在步骤4中,您只是调用默认值。

将您的代码与此进行比较:

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

每次调用先前未调用的密钥时都会生成一个新数组,并将该键值对分配给散列。

答案 1 :(得分:1)

看起来<<运算符会附加到默认数组本身,而不是处理它的副本。

 [65] pry(main)> hash = Hash.new([])
=> {}
[66] pry(main)> hash["a"] << 0
=> [0]
[67] pry(main)> hash
=> {}
[68] pry(main)> hash["b"]
=> [0]
[69] pry(main)> hash["c"]
=> [0]

编辑:它不仅仅是<<运算符,Array#push也会推送到默认数组。

答案 2 :(得分:1)

让我们从不同的角度来看待这个问题。你在数组上调用push。为什么在数组上调用push会修改哈希?数组和散列之间没有关系。

你期望在这里发生什么:

a = []

h = Hash.new(a)

a.push(1234)

您希望h改变吗?可能不是。但这是与你的代码完全相同的事情

答案 3 :(得分:-1)

原因是,当您编写h = Hash.new([])时,您创建了新的哈希值array作为不存在的密钥的默认值,当您编写h['a'].push(1243)时 - 您只需添加一个这个数组的新元素,当你尝试做一些像:

h['b'], h['c'], h['lol'] 
=> [1243]

要创建新的hash,您只需:

第一个例子:

h = {}
h['a'] = 1243

第二个例子

h = Hash.new
h['a'] = 1243