How can I initialize an Array inside a Hash in Ruby

前端 未结 3 1394
离开以前
离开以前 2020-12-28 12:22

I am trying to initialize a Hash of Arrays such as

@my_hash = Hash.new(Array.new)

so that I can:

@my_hash[\"hello\"].push(\         


        
相关标签:
3条回答
  • 2020-12-28 12:59
    @my_hash = Hash.new(Array.new)
    

    This creates exactly one array object, which is returned every time a key is not found. Since you only ever mutate that array and never create a new one, all your keys map to the same array.

    What you want to do is:

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

    or simply

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

    Passing a block to Hash.new differs from simply passing an argument in 2 ways:

    1. The block is executed every time a key is not found. Thus you'll get a new array each time. In the version with an argument, that argument is evaluated once (before new is called) and the result of that is returned every time.

    2. By doing h[k] = you actually insert the key into the hash. If you don't do this just accessing @my_hash[some_key] won't actually cause some_key to be inserted in the hash.

    0 讨论(0)
  • 2020-12-28 13:01

    The argument for Hash.new is for the default value for new hash keys, so when you pass it a reference that reference will be used for new hash keys. You're updating that reference when you call...

    hash["key"].push "value"
    

    You need to pass a new reference into the hash key before pushing values to it...

    hash["key1"] = Array.new
    hash["key1"].push "value1"
    hash["key2"] = Array.new
    hash["key2"].push "value2
    

    You could try encapsulating this into a helper method as well.

    0 讨论(0)
  • 2020-12-28 13:10

    Try this:

    @my_hash = Hash.new { |h, k| h[k] = Array.new }
    
    0 讨论(0)
提交回复
热议问题