使用键数组遍历嵌套的 Ruby 哈希
Posted
技术标签:
【中文标题】使用键数组遍历嵌套的 Ruby 哈希【英文标题】:Traverse Nested Ruby Hash With Array of Keys 【发布时间】:2017-04-03 00:28:07 【问题描述】:给定一个包含 n 层嵌套值、一个字段名和一个路径的散列
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
如何定义一种方法来检索路径末尾的字段值。
def get_value(hash, field, path)
?
end
get_value(contact, "Record", ["Account", "Team"])
=> 1234
【问题讨论】:
你的问题写得很好。下次考虑在选择答案之前稍等片刻。快速选择可能会阻止其他答案,并使仍在研究答案的人短路。 (不过,在我开始写我的答案之前,你已经选择了一个答案。) 你好@CarySwoveland - 感谢您的建议,我下次一定会这样做。刚开始真正使用 StackExchange,所以我有点菜鸟。你的回答很好。 【参考方案1】:你可以用Array#inject
: 来表示hash['Account']['Team']
然后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
顺便说一句,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
或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
【讨论】:
【参考方案2】:def get_value(contact, field, path)
path.inject(contact) |p, j| p.fetch(j, ) .fetch(field, nil)
end
【讨论】:
你可以写(path + [field]).inject(contact) |p, j| p.fetch(j, )
来简化一点。【参考方案3】:
让我们将“字段”视为“路径”的最后一个元素。那么就简单了
def grab_it(h, path)
h.dig(*path)
end
grab_it contact, ["Account", "Team", "Record"]
#=> 1234
grab_it contact, ["Account", "Team", "Rabbit"]
#=> nil
grab_it(contact, ["Account", "Team"]
# => "Closing_Sales"=>"Bob Troy", "Record"=>1234
grab_it contact, ["Account"]
#=> "Exchange"=>true, "Gmail"=>false, "Team"=>"Closing_Sales"=>"Bob Troy",
# "Record"=>1234
Hash#dig 在 v2.3 中添加。
【讨论】:
以上是关于使用键数组遍历嵌套的 Ruby 哈希的主要内容,如果未能解决你的问题,请参考以下文章
在Ruby中将嵌套哈希键从CamelCase转换为snake_case
c#用foreach遍历数组、列表时是直接获得数据元素,而foreach哈希表时,为啥获得的是命名空间名??