What is the most ruby-ish way of accessing nested hash values at arbitrary depths?
def val_for(hash, keys)
keys.reduce(hash) { |h, key| h[key] }
end
This will raise an exception if some intermediate key is not found. Note also that this is completely equivalent to keys.reduce(hash, :[])
, but this may very well confuse some readers, I'd use the block.
ruby use array tvalues to index nested hash of hash
And then there's:
keys.inject(hash, :fetch)
or for earlier Ruby versions:
keys.inject(hash) {|h, k| h[k]}
If you did want to use recursion, a more Rubyesque approach would be:
def get_value(obj, keys)
keys.empty? ? obj : get_value(obj[keys[0]], keys[1..-1])
end
Access nested hash element specified by an array of keys
hash = { "a" => { "b" => 'foo' }}
array = ["a", "b"]
array.inject(hash,:fetch)
# => "foo"
array.inject(hash,:[])
# => "foo"
How to avoid NoMethodError for missing elements in nested hashes, without repeated nil checks?
Ruby 2.3.0 introduced a new method called dig
on both Hash
and Array
that solves this problem entirely.
name = params.dig(:company, :owner, :name)
It returns nil
if the key is missing at any level.
If you are using a version of Ruby older than 2.3, you can use the ruby_dig gem or implement it yourself:
module RubyDig
def dig(key, *rest)
if value = (self[key] rescue nil)
if rest.empty?
value
elsif value.respond_to?(:dig)
value.dig(*rest)
end
end
end
end
if RUBY_VERSION < '2.3'
Array.send(:include, RubyDig)
Hash.send(:include, RubyDig)
end
Related Topics
How to Read a Gzip File Line by Line
Rails: Wkhtmltopdf Runtimeerror (Location of Wkhtmltopdf Unknown)
Stack Level Too Deep When Using Carrierwave Versions
How to Disable All Form_For Input Fields in Ruby on Rails App
Duplicating a Ruby Array of Strings
Saml 2.0 Sso for Ruby on Rails
Ruby on Rails: How to Use Oauth2::Accesstoken.Post
How to Connect to Browser Using Ruby Selenium Webdriver
Check If Array of Integers Increments in Ruby
Is Getting Converted as "\U0092" by Nokogiri in Ruby on Rails
What Are Symbols and How Do We Use Them
How to Increment/Decrement a Character in Ruby for All Possible Values
Call Before Methods in Model on Ruby
What's the Best Way to Implement Acls to a Rails Application
Gem Which Cannot Find Gem Despite It Being Installed