Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use the fetch method for nested hash?

Tags:

ruby

I have the following hash:

hash = {'name' => { 'Mike' => { 'age' => 10, 'gender' => 'm' } } }

I can access the age by:

hash['name']['Mike']['age']

What if I used Hash#fetch method? How can I retrieve a key from a nested hash?

As Sergio mentioned, the way to do it (without creating something for myself) would be by a chain of fetch methods:

hash.fetch('name').fetch('Mike').fetch('age')
like image 377
PericlesTheo Avatar asked Oct 01 '13 12:10

PericlesTheo


People also ask

How do I access nested hash?

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.

What is hash fetch?

Hash#fetch() is a Hash class method which returns a value from the hash for the given key. With no other arguments, it will raise a KeyError exception. Syntax: Hash.fetch() Parameter: Hash values. Return: value from the hash for the given key.

What is a 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.

How do you get the key of a hash in Ruby?

Ruby | Hash key() functionHash#key() is a Hash class method which gives the key value corresponding to the value. If value doesn't exist then return nil.


2 Answers

From Ruby 2.3.0 onward, you can use Hash#dig:

hash.dig('name', 'Mike', 'age')

It also comes with the added bonus that if some of the values along the way turned up to be nil, you will get nil instead of exception.

You can use the ruby_dig gem until you migrate.

like image 90
ndnenkov Avatar answered Sep 22 '22 00:09

ndnenkov


EDIT: there is a built-in way now, see this answer.


There is no built-in method that I know of. I have this in my current project

class Hash
  def fetch_path(*parts)
    parts.reduce(self) do |memo, key|
      memo[key.to_s] if memo
    end
  end
end

# usage
hash.fetch_path('name', 'Mike', 'age')

You can easily modify it to use #fetch instead of #[] (if you so wish).

like image 32
Sergio Tulentsev Avatar answered Sep 25 '22 00:09

Sergio Tulentsev