当尝试访问数组数组深处的元素时,如果元素不存在,避免出现错误“nil:NilClass”的“未定义方法`[]”的最佳方法是什么?
例如,我目前正在这样做,但对我来说似乎很糟糕:
if @foursquare['response']['groups'][0].present? && @foursquare['response']['groups'][0]['items'].present?
当尝试访问数组数组深处的元素时,如果元素不存在,避免出现错误“nil:NilClass”的“未定义方法`[]”的最佳方法是什么?
例如,我目前正在这样做,但对我来说似乎很糟糕:
if @foursquare['response']['groups'][0].present? && @foursquare['response']['groups'][0]['items'].present?
根据您的数组内容,您可以省略.present?
. Ruby 也将只取这种构造中的最后一个值,因此您可以省略该if
语句。
@foursquare['response']['groups'][0] &&
@foursquare['response']['groups'][0]['items'] &&
@foursquare['response']['groups'][0]['items'][42]
这个问题更优雅的解决方案是egonil(博客文章)、andand gem(博客文章),甚至是 Ruby 2.3 的安全导航运算符。
更新:最近的红宝石包括该#dig
方法,在这种情况下可能会有所帮助。有关更多详细信息,请参阅user513951的答案。
Ruby 2.3.0 引入了一种在两者上调用的新方法dig
,可以与新的安全导航运算符 ( ) 结合使用来解决您的问题。Hash
Array
&.
@foursquare.dig('response', 'groups')&.first&.dig('items')
nil
如果任何级别缺少值,这将返回。
if @foursquare['response']['groups'][0].to_a['items']
. . .
碰巧NilClass
实现了#to_a
返回的 a[].
这意味着您可以将每个表达式映射nil
到[]
并且通常编写单个表达式而无需测试。