How to add a key / value pair to the beginning of the hash?

My code is:

hash = { two: 2, three: 3 } def hash_add(hash, new_key, new_value) temp_hash = {} temp_hash[new_key.to_sym] = new_value temp_hash.merge!(hash) hash = temp_hash puts hash end hash_add(hash, 'one', 1) 

Inside the method puts hash returns { :one => 1, :two => 2, :three => 3 } hash1 { :one => 1, :two => 2, :three => 3 } hash1 { :one => 1, :two => 2, :three => 3 } , but when hash1 is placed in the method, it remains unchanged after that. It looks like an assignment does not carry itself out of function.

I assume that I can return the updated hash and set the hash that I want to change outside the method:

 hash = hash_add(hash, 'one', 1) 

But I just don’t understand why the assignment that I pass the hash does not stick outside the method.

I have this that works:

 def hash_add(hash, new_key, new_value) temp_hash = {} temp_hash[new_key.to_sym] = new_value temp_hash.merge!(hash) hash.clear temp_hash.each do |key, value| hash[key] = value end end 

Which gives me what I want when this method is called, but it just seems like it is too difficult to rebuild such a hash.

+8
ruby hash
source share
5 answers

Ruby passes objects to methods by value, but this value is a reference to the object, so when you set hash=temp_hash inside the add_hash method, this change applies only to this method. The hash value outside the method does not change.

 def hash_add(hash, new_key, new_value) temp_hash = {} temp_hash[new_key.to_sym] = new_value temp_hash.merge!(hash) hash = temp_hash hash end h2 = hash_add(hash, 'one', 1) hash => {:two=>2, :three=>3} h2 =>{:one=>1, :two=>2, :three=>3} 

If you want the hash to be updated, you need to replace the contents of the hash, rather than hashing the drag and drop onto a new object, as you did with clear and re-adding values. You can also do this with the replace method.

 def hash_add(hash, new_key, new_value) temp_hash = {} temp_hash[new_key.to_sym] = new_value temp_hash.merge!(hash) hash.replace temp_hash end 

There are some good charts about passing by value in " Does Ruby follow a link or by value? "

+7
source share

How about this?

 hash1 = { two: 2, three: 3 } #add a new key,value hash1 = Hash[:one,1].merge!(hash1) #=> {:one=>1, :two=>2, :three=>3} 

Example # 2:

 h = { two: 2, three: 3 } def hash_add(h,k,v) Hash[k.to_sym,v].merge!(h) end h = hash_add(h, 'one', 1) #=> {:one=>1, :two=>2, :three=>3} 
+11
source share

NOTE: this answer is old from the time that Ruby 1.8 was still around.

In general, the Ruby Hash class does not provide ordering. The behavior may vary between versions / implementations of Ruby.

See also: Saving hashing between iterations, if they are not changed?

If you want to order, you need to use the OrderedHash class, which is provided through ActiveSupport

See: http://apidock.com/rails/ActiveSupport/OrderedHash

+1
source share

At the end of the function, you simply puts enter the hash, rather than returning it. Maybe if you changed puts hash to return hash , that would work (I haven't tried it myself).

0
source share

temp_hash is a local variable that is deleted after the function returns.

0
source share

All Articles