在Ruby中将整数限制为某个范围?

时间:2013-12-03 13:40:58

标签: ruby

我有一个实例变量@limit,它必须大于0且不大于20.我目前有这样的代码:

@limit = (params[:limit] || 10).to_i
@limit = 20 if @limit > 20
@limit = 0 if @limit < 0

这看起来很难看。有没有更好的方法将整数限制为一系列值?

谢谢!

6 个答案:

答案 0 :(得分:19)

Comparable#clampavailable in Ruby 2.4

3.clamp(10, 20)
=> 10

27.clamp(10, 20)
=> 20

15.clamp(10, 20)
=> 15

答案 1 :(得分:18)

如何使用Enumerable#minEnumerable#max

例如,要限制范围0..10中的值:

x = 100
[[10, x].min, 0].max
# => 10

x = -2
[[10, x].min, 0].max
# => 0

x = 5
[[10, x].min, 0].max
# => 5

替代方案,使用Enumerable#sort

x = 100
[x, 0, 10].sort[1]
# => 10

x = -2
[x, 0, 10].sort[1]
# => 0

x = 5
[x, 0, 10].sort[1]
# => 5

答案 2 :(得分:9)

这是一个快速基准,以显示我们应该使用哪种方法。因为有人会不可避免地说“使用sort_by因为它比sort更快”,所以我添加了它。在处理复杂对象时,sort_by仅比sort快。基本对象(如整数和字符串)应由sort处理。

require 'fruity'

class Numeric
  def clamp(min, max)
    self < min ? min : self > max ? max : self
  end
end

compare do
  min_max { [[10, 100].min, 0].max }
  sort { [100, 0, 10].sort[1] }
  sort_by { [100, 0, 10].sort_by{ |v| v }[1] }
  clamp_test { 10.clamp(0, 100) }
  original {
    limit = 10
    limit = 100 if limit > 100
    limit = 0 if limit < 0
    limit
  }
end

结果如下:

Running each test 65536 times. Test will take about 8 seconds.
original is faster than clamp_test by 2x ± 1.0
clamp_test is faster than sort by 6x ± 1.0
sort is faster than min_max by 2x ± 0.1
min_max is faster than sort_by by 2x ± 0.1

有时丑陋更好。

答案 3 :(得分:6)

如果你觉得猴子修补方法,你可能会这样做:

class Numeric
  def clamp(min, max)
    self < min ? min : self > max ? max : self
  end
end

# usage
@limit = (params[:limit] || 10).clamp(0, 20)

答案 4 :(得分:1)

为方便起见,这里有一个“丑陋而且更好”的猴子补丁。解决方案在本页的其他地方赢得了Tin Man的基准测试。 (如果超出边界,立即返回应该会快一点。)

class Numeric
  def clamp(min, max)
    return min if self < min
    return max if self > max
    self
  end
end

答案 5 :(得分:-3)

(1..19).cover? @limit

有关详细信息,请参阅docs