假设:
shipping_costs = {
key1: 45,
key2: 99,
key3: nil,
key4: 24
}
假设nil = 0,获取最大值的最简洁方法是什么?
如果我在Rails控制台中运行直接shipping_costs.values.max
,我会得到:
ArgumentError: comparison of Fixnum with nil failed
在运行max之前将这些nils变为零的最简洁方法?
答案 0 :(得分:33)
如果你想保持简洁,你可以使用
shipping_costs.values.compact.max
compact
方法会从数组中删除所有nil
值。
其他答案也是好主意。但是,我更愿意拒绝这些值,而不是用数字替换它们。我认为最好知道一个数组只包含nil
值,而不是猜测0(或你选择的任何值)的来源。
答案 1 :(得分:28)
我会去:
shipping_costs.values.map(&:to_i).max
nil.to_i
是0
。
答案 2 :(得分:6)
没人提到更短的形式?,
shipping_costs.values.max_by(&:to_i)
(只是一个信息)
答案 3 :(得分:5)
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 }
答案 4 :(得分:2)
执行shipping_costs.values.reject {|v| v.nil? }.max
答案 5 :(得分:0)
要执行问题中实际要求的操作(将max
之前的nil替换为零),而又不弄乱其他任何值,并且假设您没有false
作为可能的值,您可以可以做到这一点:
shipping_costs.values.map { |x| x || 0 }.max
但是,在实际应用中,遵循@toniedzwiedz给出的答案可能会更简单,更好。