Rails:查找可能包含nil的数组的最大值

时间:2012-11-09 23:50:39

标签: ruby-on-rails ruby

假设:

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变为零的最简洁方法?

6 个答案:

答案 0 :(得分:33)

如果你想保持简洁,你可以使用 shipping_costs.values.compact.max

compact方法会从数组中删除所有nil值。

其他答案也是好主意。但是,我更愿意拒绝这些值,而不是用数字替换它们。我认为最好知道一个数组只包含nil值,而不是猜测0(或你选择的任何值)的来源。

答案 1 :(得分:28)

我会去:

shipping_costs.values.map(&:to_i).max

nil.to_i0

答案 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给出的答案可能会更简单,更好。