说我有一个像这样的哈希数组:
items = [
{:user=>1, :amount=>484},
{:user=>2, :amount=>0},
{:user=>3, :amount=>8633}
]
为了获得用户的amount
,我会这样:
items.select{|key| key[:user] == 1 }.first[:amount]
但是如果没有具有给定ID的user
,那么这不起作用:
> items.select{|key| key[:user] == 8 }.first[:amount]
# NoMethodError: undefined method `[]' for nil:NilClass
那么如果找到该项目怎么能返回amount
,但如果什么都没有,则返回0
?
首先,你可以使用find
而不是select
,因为你只需要第一场比赛。如果你想要一个单行,你可以做这样的事情:
(items.find { |key| key[:user] == 8 } || { :amount => 0 })[:amount]
如果您碰巧有Rails或ActiveSupport,那么您可以使用try
和to_i
(同时记住nil.to_i == 0
),如下所示:
items.find { |k| key[:user] == 1 }.try(:fetch, :amount).to_i
try
只是调用一种方法(在这种情况下是fetch
)但是如果接收器是nil
总是返回nil
所以nil.try(:fetch, :amount)
是nil
但some_hash.try(:fetch, :amount)
是some_hash.fetch(:amount)
,它是一个方便的工具吞下nil
s而不添加一堆额外的条件。 AFAIK,andand
gem做类似的事情而不需要所有的ActiveSupport。
您可以捕获异常NoMethodError
begin
#code you want to execute
rescue NoMethodError
puts "0"
end
三种方式:
#1
def my_method(user, items)
items.each {|h|
return h[:amount] if h.key?(:user) && h[:user] == user && h.key?(:amount)}
0
end
my_method(1, items) #=> 484
my_method(5, items) #=> 0
#2
def my_method(user, items)
items.reduce(0) { |v,h|
(h.key?(:user) && h[:user] == user && h.key?(:amount)) ? h[:amount] : v }
end
#3
def my_method(user, items)
hash = items.find { |h| h.key?(:user) && h[:user] == user) }
(hash && hash.key?(:amount)) ? hash[:amount] : 0
end
把救援0放在最后
items.select{|key| key[:user] == 8 }.first[:amount] rescue 0
这是使用一些内置Ruby回退机制的变体
items.find(->{{}}){|e| e[:user] == 8}.fetch(:amount, 0)
首先,从行的末尾开始,fetch
,它返回提供的散列键的值。使fetch
与使用常规哈希方括号不同的一点是,如果键不在那里,fetch
抛出键错误而不是返回nil
。这是一个巧妙的技巧,但另一个有用的东西是它可以采用一个可选的第二个参数,如果找不到该键,则返回默认值:
test = { a: 1, b:2 }
test[:c] #=> nil
test.fetch(:c) #=> raise KeyError
test.fetch(:c, 0) #=> 0
很方便,但你不能在nil上调用fetch
,这是find
的默认返回,如果它什么也没找到。
幸运的是,find
还允许您指定默认返回值而不是nil。您可以传递响应call
的对象,该对象将指定如何处理没有匹配的查找。
这是一个返回空哈希的短lambda:->{{}}
,在这里它作为第一个参数传递给find
,在通常的块之前
items.find(->{{}}){ |key| key[:user] == 8 } #=> {}
所有在一起:items.find(->{{}}){|e| e[:user] == 8}.fetch(:amount, 0)
- 现在find
将始终返回某种散列,它将响应fetch
,如果缺少某个键,fetch可以返回默认值。