28

鉴于:

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

4

6 回答 6

43

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

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

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

于 2012-11-09T23:56:05.253 回答
33

我会去:

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

nil.to_i0

于 2012-11-09T23:52:42.597 回答
8

没有人提到更短的形式?,

shipping_costs.values.max_by(&:to_i)

(只是一个信息)

于 2014-03-28T10:03:00.187 回答
7

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 }
于 2012-11-10T02:46:32.740 回答
4

shipping_costs.values.reject {|v| v.nil? }.max

于 2012-11-09T23:52:55.527 回答
2

要执行问题中实际请求的操作(将 nils 替换为之前的零max),而不弄乱任何其他值,并假设您没有false可能的值,您可以这样做:

shipping_costs.values.map { |x| x || 0 }.max

但是,在实际应用中,遵循@toniedzwiedz 给出的答案可能会更简单、更好。

于 2018-12-26T20:28:48.937 回答