Ruby哈希与推送到数组的交互

Ruby哈希与推送到数组的交互,ruby,hash,Ruby,Hash,那么让我们假设我做了以下工作: lph = Hash.new([]) #=> {} lph["passed"] << "LCEOT" #=> ["LCEOT"] lph #=> {} <-- Expected that to have been {"passed" => ["LCEOT"]} lph["passed"] #=> ["LCEOT"] lph["passed"]

那么让我们假设我做了以下工作:

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"]}
lph=Hash.new([])#=>
lph[“通过”][“LCEOT”]
lph#=>{}[“LCEOT”]}
lph[“通过”]#=>[“LCEOT”]
lph[“通过”]=lph[“通过”]{“通过”=>[“LCEOT”,“HJKL”]}
我对此感到惊讶。有几个问题:

  • 为什么在我将第二个字符串推到数组上之前它不会被设置?背景中发生了什么
  • 从本质上讲,ruby更惯用的方式是什么。我有一个散列、一个键和一个值,我想在与该键关联的数组中结束。如何在第一次将与键关联的数组中的值推送到散列中。在以后使用该键时,我只想将d添加到数组中 为什么在我将第二个字符串推到数组上之前它不会被设置? 简言之;因为直到将第二个字符串添加到数组中时,才在哈希中设置任何内容

    背景中发生了什么? 为了了解背景中发生了什么,让我们一次只看一行:

    lph = Hash.new([])       #=> {}
    
    这将创建一个空哈希,配置为在访问不存在的密钥时返回
    []
    对象

    lph["passed"] << "LCEOT" #=> ["LCEOT"]
    
    lph
    仍然是空的
    Hash
    。我们在任何时候都没有向
    散列添加任何内容。我们在其默认值中添加了一些内容,但这不会改变lph本身

    lph["passed"]        #=> ["LCEOT"]
    
    这就是它变得有趣的地方。请记住,当我们仔细阅读上面的
    value时—“如果该散列随后被一个与散列条目不对应的键访问,则返回的值取决于用于创建散列的new的样式”

    新(obj)→ 新杂凑 …如果指定了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.
    
    _数组=[]
    h=Hash.new(_数组)
    h['foo'][1]
    #因为找不到键“foo”
    # ... 返回默认值(_数组)
    # ... 1被推到它上面(因此[1])。
    _数组#=>[1]
    因为键'foo'仍然没有值。
    
    您可能希望使用块形式:

    新的{散列,键{块}→ 新杂凑 …如果指定了块,则将使用哈希对象和键调用该块,并应返回默认值。如果需要,块负责将值存储在散列中

    例如:

    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] }
    
    h=Hash.new{| Hash,key | Hash[key]=[]}#为缺少的键指定一个新数组作为默认数组。
    h['foo'][1]
    h['foo'][1,2]
    h['bar'][3]
    h#=>{'foo'=>[1,2],'bar'=>[3]}
    
    +1引用文档中导致此问题的确切行为
    lph["passed"] = lph["passed"] << "HJKL"
    
    >> lph = Hash.new { [] }
    => {}
    >> lph["passed"] <<= "LCEOT"
    => ["LCEOT"]
    >> lph
    => {"passed"=>["LCEOT"]}
    
    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.
    
    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] }