30Dec/092
Ruby – Getting deeply nested values from a hash in one line of code
I occasionally have deeply nested values in a hash that I need to get to, for example:
1 2 3 4 5 6 7 8 | @event = { #... *SNIP* ... :coordinator => { :api_license => { :key => "SECRET COOL KEY" } } } |
What really sucks is to do things like:
1 2 3 | if @event[:coordinator] && @event[:coordinator][:api_license] @key_i_need = @event[:coordinator][:api_license][:key] end |
What's the fix? A seek method for a hash, throw this in your core extensions files/folders or where ever.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | class Hash def seek(*_keys_) last_level = self sought_value = nil _keys_.each_with_index do |_key_, _idx_| if last_level.is_a?(Hash) && last_level.has_key?(_key_) if _idx_ + 1 == _keys_.length sought_value = last_level[_key_] else last_level = last_level[_key_] end else break end end sought_value end end |
Now you can do this:
1 | @key_i_need = @event.seek :coordinator, :api_license, :key |
If there is any subhash that doesn't exist on the way to the value or if the value itself doesn't exist, nil is returned.
This is really great if you are passing around a lot of JSON data between applications and need to get to one specific value and you don't want to ugly up your code.
March 14th, 2011 - 08:28
Love this! could also use http://gamphani.blogspot.com/2011/03/iterate-through-variable-depth-hash-in.html
November 28th, 2012 - 18:35
Flippin brilliant. This should be added to ruby core.