Nicholas Erdenberger Nicholas Erdenberger - 19 days ago 6
Ruby Question

Traverse Nested Ruby Hash With Array of Keys

Given a hash with n levels of nested values, a field name, and a path

contact = {
"Email" => "bob@bob.com",
"Account" => {
"Exchange" => true,
"Gmail" => false,
"Team" => {
"Closing_Sales" => "Bob Troy",
"Record" => 1234
}
}
}

field = "Record"
path = ["Account", "Team"] #Must support arbitrary path length


How can one define a method that would retrieve the field value at the end of the path.

def get_value(hash, field, path)
?
end

get_value(contact, "Record", ["Account", "Team"])
=> 1234

Answer

You can use Array#inject: to mean hash['Account']['Team'] then, return_value_of_inject['Record']:

def get_value(hash, field, path)
  path.inject(hash) { |hash, x| hash[x] }[field]
end

get_value(contact, field, path) # => 1234

BTW, how about get_value(contact, ['Account', 'Team', 'Record']) ?

def get_value2(hash, path)
  path.inject(hash) { |hash, x| hash[x] }
end

get_value2(contact, ['Account', 'Team', 'Record']) # => 1234

or get_value(contact, 'Account.Team.Record')

def get_value3(hash, path)
  path.split('.').inject(hash) { |hash, x| hash[x] }
end

get_value3(contact, 'Account.Team.Record')   # => 1234