32

我写了以下代码,它保持x在范围内(a..b)。在伪代码中:

(if x < a, x = a; if x > b, x = b)

在 Ruby 中,它会是这样的:

x = [a, [x, b].min].max

由于它是非常基本且有用的功能,我想知道在 ruby​​ 中是否有本地方法可以做到这一点。

从 Ruby 2.3.3 开始,显然没有这样的方法,那么最短/更易读的方法是什么?

我发现:

x = [a, x, b].sort[1]

到目前为止,但我不确定它是否更具可读性。

4

5 回答 5

58

Ruby 2.4.0 引入Comparable#clamp

523.clamp(0, 100)        #=> 100
于 2012-08-18T23:13:09.273 回答
37

我自己的答案:不

然而

x = [a, x, b].sort[1]

是一个解决方案。

于 2014-02-27T14:39:52.240 回答
12

我这样做了:

class Numeric
  def clamp min, max
    [[self, max].min, min].max
  end
end

所以每当我想夹住任何东西时,我都可以打电话:

x.clamp(min, max)

我觉得这很可读。

于 2014-02-07T20:10:35.863 回答
0

这是我从实际实现中大量借鉴的解决方案:

unless Comparable.method_defined? :clamp
  module Comparable
    def clamp min, max
      if max-min<0
        raise ArgumentError, 'min argument must be smaller than max argument'
      end
      self>max ? max : self<min ? min : self
    end
  end
end
于 2017-11-18T03:08:33.563 回答
-1

在我看来,目前最吸引人的解决方案是排序选项:

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

当您不介意猴子修补现有的核心类时。我认为范围类是钳位方法的良好候选者

class Range
  def clamp(v)
    [min,v,max].sort[1]
  end
end

(min..max).clamp(v)

或普通数组对象。我不喜欢这样,因为钳位函数仅适用于 3 元素数组

class Array
    def clamp
      sort[1]
    end
end

你可以这样称呼它:

[a,x,b].clamp
于 2016-07-26T14:06:00.870 回答