Ruby优雅方式返回最小值/最大值,如果值超出范围

时间:2013-04-24 17:21:02

标签: ruby

所以我正在编写一个程序来建模流程并需要计算费用。逻辑是,如果费用金额小于最低金额,则使用最低金额,如果金额大于最大金额,则使用最大金额。

我当然可以在多行上实现这一点,但有兴趣知道在Ruby中是否有更优雅的方式来实现这一点。

fee_amount = <whatever logic I need>
if fee_amount < min return min
if fee_amount > max return max
return fee_amount

8 个答案:

答案 0 :(得分:9)

如果你正在寻找一个不那么丑陋(或至少是短暂的)单线:

[min,fee_amount,max].sort[1]

绝对不是Rubyish,因为乍看之下并不直观。

答案 1 :(得分:6)

如果只是一次,我会推荐Shawn Balestracci的答案,这是最美丽的。

或者,以下是我个人图书馆的一些方法:

module Comparable
  def at_least other; self < other ? other : self end
  def at_most other; self > other ? other : self end
end

我这样用:

fee_amount = <whatever logic I need>.at_least(min).at_most(max)

答案 2 :(得分:4)

使用后缀条件,这将是红宝石风格。

return min if fee_amount < min
return max if fee_amount > max
fee_amount

答案 3 :(得分:2)

这是一个简短的单行:

 [[min, fee_amount].max, max].min

你应该将它包装在一个带有描述性名称的方法中,我的想法是:

 def limit_by_range(value, min, max)
   [[min, value].max, max].min
 end

答案 4 :(得分:2)

Ruby 2.4添加了Comparable#clamp来做到这一点

fee_amount.clamp(min, max)

https://blog.bigbinary.com/2016/12/13/ruby-2-4-adds-comparable-clamp-method.html

答案 5 :(得分:1)

在一行中没有优雅的方式;你可以通过将这么多逻辑塞进一行代码来使这个更少更优雅。

现有代码可以大幅清理:

fee_amount = <logic>
fee_amount = min if fee_amount < min
fee_amount = max if fee_amount > max

对于这个非常难看的单行......

fee_amount = if fee_amount < min then min elsif fee_amount > max then max else fee_amount end

答案 6 :(得分:1)

n = (n <= max || n >= min) ? n : (n < min ? min : max)

有点通用

答案 7 :(得分:0)

# stabby lambda function:
map = ->(val, min, max) { [min, val, max].sort[1] }

# call stabby function:
map.call(2.5, 1, 3)
=> 2.5
# or shorter:
map[2.5, 1, 3]
=> 2.5