确定是否定义的最简洁方法是什么,如果或为零@hash[:key1][:key2]
则不会引发错误?@hash
@hash[:key1]
defined?(@hash[:key1][:key2])
如果存在则返回True @hash[:key1]
(不判断是否:key2
定义)
确定是否定义的最简洁方法是什么,如果或为零@hash[:key1][:key2]
则不会引发错误?@hash
@hash[:key1]
defined?(@hash[:key1][:key2])
如果存在则返回True @hash[:key1]
(不判断是否:key2
定义)
使用 ActiveSupport (Rails) 或 Backports 时,您可以使用try
:
@hash[:key1].try(:fetch, :key2)
你甚至可以@hash
处理nil
:
@hash.try(:fetch, :key1).try(:fetch, :key2)
如果您想@hash
始终为丢失的键返回哈希:
@hash = Hash.new { |h,k| h[k] = {} }
@hash[:foo] # => {}
你也可以定义这个递归:
def recursive_hash
Hash.new { |h,k| h[k] = recursive_hash }
end
@hash = recursive_hash
@hash[:foo][:bar][:blah] = 10
@hash # => {:foo => {:bar => {:blah => 10}}}
但要回答你的问题:
module HasNestedKey
Hash.send(:include, self)
def has_nested_key?(*args)
return false unless sub = self[args.shift]
return true if args.empty?
sub.respond_to?(:has_nested_key?) and sub.has_nested_key?(*args)
end
end
@hash.has_nested_key? :key1, :key2
也许我错过了一些东西,但如果你关心的只是简洁......为什么不:
@hash && @hash[:key1] && @hash[:key1][:key2]
或者如果你想保存几个字符
@hash && (h = @hash[:key1]) && h[:key2]
如果其中任何部分失败,则返回,nil
否则返回与:key2
or关联的值true
。
defined?
即使不存在也返回 true的原因:key2
是因为它只是检查您引用的对象是否存在,在这种情况下,该方法是散列上确实存在[]
的方法的别名,但如果返回 nil ,没有 fetch 方法,它会返回。话虽如此,如果您必须深入研究嵌入式哈希,那么在某些时候调用会变得更有效率:fetch
@hash[:key1]
nil
nil
n
defined?(@hash[:key1][:key2][:key3]) && @hash[:key1][:key2][:key3]
使用哈希#fetch
您可以使用默认为的Hash#fetch{}
方法,这样has_key?
即使第一级键不存在也可以安全调用。例如
!hash.nil? && hash.fetch(key1, {}).has_key?(key2)
选择
或者,您可以使用条件运算符,例如
!hash.nil? && (hash.has_key?(key1) ? hash[key1].has_key?(key2) : false)
即如果hash
没有密钥key1
,则返回false
而不寻找第二级密钥。如果确实有,key1
则返回检查key1's
值的结果key2
。
此外,如果您想在调用它之前检查该hash[key1]'s
值是否有方法:has_key?
!hash.nil? && (hash.has_key?(key1) ? hash[key1].respond_to?(:has_key?) &&
hash[key1].has_key?(key2) : false)
@hash[:key1].has_key? :key2
如果您不关心从 中区分不存在@hash[:key1][:key2]
(在 3 个级别中的任何一个级别)@hash[:key1][:key2] == nil
,那么这非常干净并且适用于任何深度:
[:key1,:key2].inject(hash){|h,k| h && h[k]}
如果您想nil
被视为现有,请改用:
(hash[:key1].has_key?(:key2) rescue false)
我刚刚发现的另一种选择是使用seek
方法扩展 Hash。技术来自Corey O'Daniel。
将其粘贴在初始化程序中:
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
然后只需调用:
@key_i_need = @hash.seek :one, :two, :three
你会得到这个值,如果它不存在,你会得到 nil 。