Tod*_*d R 56 ruby hash coding-style
考虑存储在哈希中的"人".两个例子是:
fred = {:person => {:name => "Fred", :spouse => "Wilma", :children => {:child => {:name => "Pebbles"}}}}
slate = {:person => {:name => "Mr. Slate", :spouse => "Mrs. Slate"}}
Run Code Online (Sandbox Code Playgroud)
如果"人"没有任何子女,则"儿童"元素不存在.所以,对于Slate先生,我们可以检查他是否有父母:
slate_has_children = !slate[:person][:children].nil?
Run Code Online (Sandbox Code Playgroud)
那么,如果我们不知道"slate"是一个"人"哈希呢?考虑:
dino = {:pet => {:name => "Dino"}}
Run Code Online (Sandbox Code Playgroud)
我们不能再轻易检查孩子了:
dino_has_children = !dino[:person][:children].nil?
NoMethodError: undefined method `[]' for nil:NilClass
Run Code Online (Sandbox Code Playgroud)
那么,你如何检查哈希的结构,特别是如果它被深深嵌套(甚至比这里提供的例子更深)?也许更好的问题是:这样做的"红宝石方式"是什么?
tad*_*man 86
最明显的方法是简单地检查每一步:
has_children = slate[:person] && slate[:person][:children]
Run Code Online (Sandbox Code Playgroud)
使用.nil?实际上只有在使用false作为占位符值时才需要,实际上这种情况很少见.通常你可以简单地测试它是否存在.
更新:如果您使用的是Ruby 2.3或更高版本,则会有一个内置
dig方法,可以执行此答案中描述的内容.
如果没有,您还可以定义自己的哈希"挖掘"方法,这可以大大简化:
class Hash
def dig(*path)
path.inject(self) do |location, key|
location.respond_to?(:keys) ? location[key] : nil
end
end
end
Run Code Online (Sandbox Code Playgroud)
此方法将检查方法的每个步骤,并避免绊倒对nil的调用.对于浅层结构,实用程序有些限制,但对于深度嵌套的结构,我发现它非常有用:
has_children = slate.dig(:person, :children)
Run Code Online (Sandbox Code Playgroud)
您也可以使其更加健壮,例如,测试:children条目是否实际填充:
children = slate.dig(:person, :children)
has_children = children && !children.empty?
Run Code Online (Sandbox Code Playgroud)
Mar*_*rez 21
使用Ruby 2.3,我们将支持安全导航操作员:https: //www.ruby-lang.org/en/news/2015/11/11/ruby-2-3-0-preview1-released/
has_children 现在可以写成:
has_children = slate[:person]&.[](:children)
Run Code Online (Sandbox Code Playgroud)
dig 正在添加:
has_children = slate.dig(:person, :children)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
44820 次 |
| 最近记录: |