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

Jam*_*ren 23 ruby ruby-on-rails

鉴于:

shipping_costs = {
  key1: 45,
  key2: 99,
  key3: nil,
  key4: 24
}
Run Code Online (Sandbox Code Playgroud)

假设nil = 0,获得最大值的最简洁方法是什么?

如果我shipping_costs.values.max在Rails控制台中直接运行,我会得到:

ArgumentError: comparison of Fixnum with nil failed
Run Code Online (Sandbox Code Playgroud)

在运行max之前将这些nils变成零的最干净的方法?

ton*_*edz 36

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

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

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

  • 这个答案适用于非整数数字 (4认同)

Sha*_*ell 30

我会去:

shipping_costs.values.map(&:to_i).max
Run Code Online (Sandbox Code Playgroud)

nil.to_i0.

  • 这里有一个潜在的错误源,就是当你想要-1时,这将为数组[nil,-2,-4,-1]返回最大值为零.出于这个原因,我更喜欢@toniedzwiedz的解决方案. (3认同)
  • 尽管该问题确实指定了应该假定 `nil` 值是 `= 0`。 (3认同)
  • 在技​​术上最正确和具体的问题,所以你得到答案.我可能会做汤姆的解决方案.:) (2认同)
  • 另一个限制是,这也会尝试将非 nil 值转换为整数,如果其中有十进制值或其他类型(如字符串或日期),这将是有问题的。这个问题没有问这个! (2认同)

sha*_*jin 7

没人提到更短的形式?

shipping_costs.values.max_by(&:to_i)
Run Code Online (Sandbox Code Playgroud)

(只是一个信息)


the*_*Man 6

max采取一个块,允许您进行比较,类似于如何sort工作:

[45, 99, nil, 24].max{ |a,b| (a || 0) <=> (b || 0) }
=> 99
Run Code Online (Sandbox Code Playgroud)

要么:

[45, 99, nil, 24].max{ |a,b| a.to_i <=> b.to_i }
=> 99
Run Code Online (Sandbox Code Playgroud)

这使您可以在比较发生之前强制显示您想要/需要的值.

对于您的情况,shipping_costs.values将返回您需要比较的数组,因此:

shipping_costs.values.max{ |a,b| a.to_i <=> b.to_i }
Run Code Online (Sandbox Code Playgroud)