Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to assign hash['a']['b']= 'c' if hash['a'] doesn't exist?

Tags:

Is there any way simpler than

if hash.key?('a')   hash['a']['b'] = 'c'  else     hash['a'] = {}   hash['a']['b'] = 'c'  end 
like image 283
Radek Avatar asked May 04 '11 04:05

Radek


People also ask

How do you check if a value exists in a hash?

Overview. A particular value can be checked to see if it exists in a certain hash by using the has_value?() method. This method returns true if such a value exists, otherwise false .

What is returned if you pass a key that doesnt exist into a hash?

Typically when an element is passed into a hash with no matching key, the hash returns nil .

How do you check if a key exists in a hash Ruby?

Overview. We can check if a particular hash contains a particular key by using the method has_key?(key) . It returns true or false depending on whether the key exists in the hash or not.

How do you make hash hash in Ruby?

Just like arrays, hashes can be created with hash literals. Hash literals use the curly braces instead of square brackets and the key value pairs are joined by =>. For example, a hash with a single key/value pair of Bob/84 would look like this: { "Bob" => 84 }.


1 Answers

The easiest way is to construct your Hash with a block argument:

hash = Hash.new { |h, k| h[k] = { } } hash['a']['b'] = 1 hash['a']['c'] = 1 hash['b']['c'] = 1 puts hash.inspect # "{"a"=>{"b"=>1, "c"=>1}, "b"=>{"c"=>1}}" 

This form for new creates a new empty Hash as the default value. You don't want this:

hash = Hash.new({ }) 

as that will use the exact same hash for all default entries.

Also, as Phrogz notes, you can make the auto-vivified hashes auto-vivify using default_proc:

hash = Hash.new { |h, k| h[k] = Hash.new(&h.default_proc) } 

UPDATE: I think I should clarify my warning against Hash.new({ }). When you say this:

h = Hash.new({ }) 

That's pretty much like saying this:

h = Hash.new h.default = { } 

And then, when you access h to assign something as h[:k][:m] = y, it behaves as though you did this:

if(h.has_key?(:k))     h[:k][:m] = y else     h.default[:m] = y end 

And then, if you h[:k2][:n] = z, you'll end up assigning h.default[:n] = z. Note that h still says that h.has_key?(:k) is false.

However, when you say this:

h = Hash.new(0) 

Everything will work out okay because you will never modified h[k] in place here, you'll only read a value from h (which will use the default if necessary) or assign a new value to h.

like image 73
mu is too short Avatar answered Oct 27 '22 01:10

mu is too short