1

How do I get the value of a key or the key's presence from a nested hash?

For example:

a = { "a"=> { "b" => 1, "c" => { "d" => 2, "e" => { "f" => 3 } }}, "g" => 4}

Is there any direct method to get the value of "f"? Or is there a method to know the presence of key in the nested hash?

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Ankush Kataria
  • 323
  • 4
  • 13
  • Have a look [here](http://stackoverflow.com/questions/3748744/traversing-a-hash-recursively-in-ruby) for some recursive hash work. – ChuckJHardy Jun 05 '13 at 12:28
  • You can take a look here - http://metaskills.net/2012/03/12/store-configurable-a-lesson-in-recursion-in-ruby/ – Arup Rakshit Jun 05 '13 at 12:44
  • Possible duplicate of [Ruby Style: How to check whether a nested hash element exists](http://stackoverflow.com/questions/1820451/ruby-style-how-to-check-whether-a-nested-hash-element-exists) – Ryenski May 25 '16 at 18:54

3 Answers3

5
%w[a c e f].inject(a, &:fetch) # => 3
%w[a c e x].inject(a, &:fetch) # > Error key not found: "x"
%w[x].inject(a, &:fetch) # => Error key not found: "x"

Or, to avoid errors:

%w[a c e f].inject(a, &:fetch) rescue "Key not found" # => 3
%w[a c e x].inject(a, &:fetch) rescue "Key not found"  # => Key not found
%w[x].inject(a, &:fetch) rescue "Key not found"  # => Key not found
sawa
  • 165,429
  • 45
  • 277
  • 381
2
def is_key_present?(hash, key)
  return true if hash.has_key?(key)
  hash.each do |k, v|
    return true if v.kind_of?(Hash) and is_key_present?(v, key)
  end
  false
end

> is_key_present?(a, 'f')
=> true
0

A slightly different version of the answer provided by sawa:

%w[a c e f].inject(a) { |a, key| a.fetch(key, {}) }

The difference is that an empty hash will be returned if a key is not found at any point in the hierarchy, rather than an exception being raised. It is probably better to raise an exception in most cases, but this is an alternative depending on your use case.

Alissa H
  • 450
  • 4
  • 7