I have a Hash
and I want to insert some data into it at a deep level, but a key might be missing at any level. So, I am conditionally initializing it before updating its value at every level.
What would be a better way to write this or an approach that can make code less ugly?
data[:foo] ||= {}
data[:foo][:bar] ||= {}
data[:foo][:bar][:baz] ||= []
data[:foo][:bar][:baz] << 99
Accessing a specific element in a nested hash is very similar to a nested array. It is as simple as calling hash[:x][:y] , where :x is the key of the hash and :y is the key of the nested hash.
Nested hashes allow us to further group, or associate, the data we are working with. They help us to deal with situations in which a category or piece of data is associated not just to one discrete value, but to a collection of values.
We can merge two hashes using the merge() method. When using the merge() method: Each new entry is added to the end. Each duplicate-key entry's value overwrites the previous value.
Use hash autovivification:
data = Hash.new { |h, k| h[k] = h.dup.clear }
#⇒ {}
# or, credits to @Amadan:
data = Hash.new { |h, k| h[k] = Hash.new(&h.default_proc) }
#⇒ {}
data[:foo][:bar][:baz] = 42
data
#⇒ {:foo=>{:bar=>{:baz=>42}}}
The trick used here is we use Hash#default_proc
to create nested keys.
For your case:
(data[:foo][:bar][:baz] = []) << 99
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With