作者热门文章
- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
通常,解析 XML 或 JSON 会返回哈希、数组或它们的组合。通常,解析无效数组会导致各种 TypeError
、NoMethodError
、意外的 nils 等。
例如,我有一个response
对象,想要找到以下元素:
response['cars'][0]['engine']['5L']
如果响应是
{ 'foo' => { 'bar' => [1, 2, 3] } }
当我只想看到 nil
时,它会抛出一个 NoMethodError
异常。
有没有一种简单的方法来查找元素,而无需诉诸大量的 nil 检查、救援或 Rails try
方法?
最佳答案
Casper 就在我之前,他使用了相同的想法(不知道我在哪里找到它,是很久以前的事了)但我相信我的解决方案更可靠
module DeepFetch
def deep_fetch(*keys, &fetch_default)
throw_fetch_default = fetch_default && lambda {|key, coll|
args = [key, coll]
# only provide extra block args if requested
args = args.slice(0, fetch_default.arity) if fetch_default.arity >= 0
# If we need the default, we need to stop processing the loop immediately
throw :df_value, fetch_default.call(*args)
}
catch(:df_value){
keys.inject(self){|value,key|
block = throw_fetch_default && lambda{|*args|
# sneak the current collection in as an extra block arg
args << value
throw_fetch_default.call(*args)
}
value.fetch(key, &block) if value.class.method_defined? :fetch
}
}
end
# Overload [] to work with multiple keys
def [](*keys)
case keys.size
when 1 then super
else deep_fetch(*keys){|key, coll| coll[key]}
end
end
end
response = { 'foo' => { 'bar' => [1, 2, 3] } }
response.extend(DeepFetch)
p response.deep_fetch('cars') { nil } # nil
p response.deep_fetch('cars', 0) { nil } # nil
p response.deep_fetch('foo') { nil } # {"bar"=>[1, 2, 3]}
p response.deep_fetch('foo', 'bar', 0) { nil } # 1
p response.deep_fetch('foo', 'bar', 3) { nil } # nil
p response.deep_fetch('foo', 'bar', 0, 'engine') { nil } # nil
关于ruby - 解析哈希和数组的简单方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14696191/
我是一名优秀的程序员,十分优秀!