Ruby Hash交互与推送到数组

Noa*_*ark 4 ruby hash

所以我要说我做了以下事情:

lph = Hash.new([])       #=> {}
lph["passed"] << "LCEOT" #=> ["LCEOT"]
lph                      #=> {} <-- Expected that to have been {"passed" => ["LCEOT"]}
lph["passed"]            #=> ["LCEOT"]
lph["passed"] = lph["passed"] << "HJKL"
lph #=> {"passed"=>["LCEOT", "HJKL"]}
Run Code Online (Sandbox Code Playgroud)

我对此感到惊讶.几个问题:

  1. 为什么在我将第二个字符串推送到数组之前它不会被设置?背景中发生了什么?
  2. 什么是惯用的红宝石方式基本上说.我有一个哈希,一个键和一个值,我希望最终在与键相关联的数组中.如何在第一次将与键关联的数组中的值推送到哈希中.在以后的所有密钥使用中,我只想添加到数组中.

mae*_*ics 6

仔细阅读Ruby Hash.new文档 - "如果随后通过与散列条目不对应的密钥访问此散列,则返回的值取决于用于创建散列的新样式".

new(obj)→new_hash

...如果指定了obj,则此单个对象将用于所有默认值.

在您的示例中,您尝试将某些内容推送到与不存在的键相关联的值上,因此您最终会改变最初用于构造哈希的相同匿名数组.

the_array = []
h = Hash.new(the_array)
h['foo'] << 1 # => [1]
# Since the key 'foo' was not found
# ... the default value (the_array) is returned
# ... and 1 is pushed onto it (hence [1]).
the_array # => [1]
h # {} since the key 'foo' still has no value.
Run Code Online (Sandbox Code Playgroud)

您可能想要使用块形式:

new {| hash,key | 阻止}→new_hash

...如果指定了一个块,它将使用哈希对象和键调用,并应返回默认值.如果需要,块负责将值存储在哈希中.

例如:

h = Hash.new { |hash, key| hash[key] = [] } # Assign a new array as default for missing keys.
h['foo'] << 1 # => [1]
h['foo'] << 2 # => [1, 2]
h['bar'] << 3 # => [3]
h # => { 'foo' => [1, 2], 'bar' => [3] }
Run Code Online (Sandbox Code Playgroud)