鉴于:
shipping_costs = {
key1: 45,
key2: 99,
key3: nil,
key4: 24
}
假设 nil = 0,获得这些键的最大值的最干净的方法是什么?
如果我shipping_costs.values.max
在 Rails 控制台中直接运行,我会得到:
ArgumentError: comparison of Fixnum with nil failed
在运行 max 之前将这些 nil 变为零的最干净的方法?
鉴于:
shipping_costs = {
key1: 45,
key2: 99,
key3: nil,
key4: 24
}
假设 nil = 0,获得这些键的最大值的最干净的方法是什么?
如果我shipping_costs.values.max
在 Rails 控制台中直接运行,我会得到:
ArgumentError: comparison of Fixnum with nil failed
在运行 max 之前将这些 nil 变为零的最干净的方法?
如果你想保持简洁,你可以使用
shipping_costs.values.compact.max
该方法从数组compact
中删除所有值。nil
其他答案也是好主意。但是,我更愿意拒绝这些值,而不是用数字替换它们。我认为最好知道一个数组只包含nil
值,而不是猜测 0(或您选择的任何值)来自哪里。
我会去:
shipping_costs.values.map(&:to_i).max
nil.to_i
是0
。
没有人提到更短的形式?,
shipping_costs.values.max_by(&:to_i)
(只是一个信息)
max
接受一个块,允许您进行比较,类似于sort
工作原理:
[45, 99, nil, 24].max{ |a,b| (a || 0) <=> (b || 0) }
=> 99
或者:
[45, 99, nil, 24].max{ |a,b| a.to_i <=> b.to_i }
=> 99
这使您可以在比较发生之前强制您想要/需要的值。
对于您的情况,shipping_costs.values
将返回您需要比较的数组,因此:
shipping_costs.values.max{ |a,b| a.to_i <=> b.to_i }
做shipping_costs.values.reject {|v| v.nil? }.max
要执行问题中实际请求的操作(将 nils 替换为之前的零max
),而不弄乱任何其他值,并假设您没有false
可能的值,您可以这样做:
shipping_costs.values.map { |x| x || 0 }.max
但是,在实际应用中,遵循@toniedzwiedz 给出的答案可能会更简单、更好。