Append key/value pair to hash with << in Ruby

RubyHash

Ruby Problem Overview


In Ruby, one can append values to existing arrays using <<:

a = []
a << "foo"

but, can you also append key/value pairs to an existing hash?

h = {}
h << :key "bar"

I know you can do:

h[:key] = ""
h[:key] << "bar"

but that's not I want.

Thanks.

Ruby Solutions


Solution 1 - Ruby

There is merge!.

h = {}
h.merge!(key: "bar")
# => {:key=>"bar"}

Solution 2 - Ruby

Since hashes aren't inherently ordered, there isn't a notion of appending. Ruby hashes since 1.9 maintain insertion order, however. Here are the ways to add new key/value pairs.

The simplest solution is

h[:key] = "bar"

If you want a method, use store:

h.store(:key, "bar")

If you really, really want to use a "shovel" operator (<<), it is actually appending to the value of the hash as an array, and you must specify the key:

h[:key] << "bar"

The above only works when the key exists. To append a new key, you have to initialize the hash with a default value, which you can do like this:

h = Hash.new {|h, k| h[k] = ''}
h[:key] << "bar"

You may be tempted to monkey patch Hash to include a shovel operator that works in the way you've written:

class Hash
  def <<(k,v)
    self.store(k,v)
  end
end

However, this doesn't inherit the "syntactic sugar" applied to the shovel operator in other contexts:

h << :key, "bar" #doesn't work
h.<< :key, "bar" #works

Solution 3 - Ruby

No, I don't think you can append key/value pairs. The only thing closest that I am aware of is using the store method:

h = {}
h.store("key", "value")

Solution 4 - Ruby

Perhaps you want Hash#merge ?

1.9.3p194 :015 > h={}
 => {} 
1.9.3p194 :016 > h.merge(:key => 'bar')
 => {:key=>"bar"} 
1.9.3p194 :017 > 

If you want to change the array in place use merge!

1.9.3p194 :016 > h.merge!(:key => 'bar')
 => {:key=>"bar"} 

Solution 5 - Ruby

Similar as they are, merge! and store treat existing hashes differently depending on keynames, and will therefore affect your preference. Other than that from a syntax standpoint, merge!'s key: "value" syntax closely matches up against JavaScript and Python. I've always hated comma-separating key-value pairs, personally.

hash = {}
hash.merge!(key: "value")
hash.merge!(:key => "value")
puts hash

> {:key=>"value"}

hash = {}
hash.store(:key, "value")
hash.store("key", "value")
puts hash

> {:key=>"value", "key"=>"value"}

To get the shovel operator << working, I would advise using Mark Thomas's answer.

Solution 6 - Ruby

I had to do a similar thing but I needed to add values with same keys. When I use merge or update I can't push values with same keys. So I had to use array of hashes.

    my_hash_static = {:header =>{:company => 'xx', :usercode => 'xx', :password => 'xx',
                      :type=> 'n:n', :msgheader => from}, :body=>[]}
    my_hash_dynamic = {:mp=>{:msg=>message, :no=>phones} }        
    my_hash_full = my_hash_static[:body].push my_hash_dynamic

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjcarpioView Question on Stackoverflow
Solution 1 - RubysawaView Answer on Stackoverflow
Solution 2 - RubyMark ThomasView Answer on Stackoverflow
Solution 3 - RubyPericlesTheoView Answer on Stackoverflow
Solution 4 - RubyMichael DurrantView Answer on Stackoverflow
Solution 5 - RubykayleeFrye_onDeckView Answer on Stackoverflow
Solution 6 - RubyCanerView Answer on Stackoverflow