有没有一种方法可以限制/夹紧一个数字?

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]

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


1
你已经回答了自己的问题 - 很好地使用了排序函数。我认为你不会得到比那更易读的东西了。 - xiy
2
你可能的意思是:x2 = [a,[x,b].min] .max。在我的看法中它看起来不错,使用基本通用方法来构建其余部分。 - tokland
有趣的sort用法..使整个过程独立于顺序.. - Karthik T
我喜欢你的神秘版本。你应该将它作为答案提交,这样我就可以点赞了。 - drewish
@drewish 谢谢。我在某个地方找到了它(如果我没记错的话,是在 R 社区)。我创建了一个答案。 - mb14
显示剩余2条评论
5个回答

62

13
最好的部分是:Ruby没有clamp方法的原因是他们无法停止争论该如何命名这个函数。 - user481081
现在这个终于被添加了。 - fgb
2
哈哈,我实现了Comparable#clamp。他们花了很长时间才合并我的补丁...;-) - nerdinand

37

我的回答是:不行

然而

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

是一个解决方案。


18
不撒谎,那很性感。 - henrebotha
3
我认为这可能是我见过的最漂亮的代码行。 - anon
2
很酷的是,你放置min、max和x的顺序甚至都不重要。 - Fritzz

12

我做了这件事:

class Numeric
  def clamp min, max
    [[self, max].min, min].max
  end
end
所以,每当我想夹住任何东西时,我只需调用:

x.clamp(min, max)

我觉得这很易读。


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

-1

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

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

当您不介意猴子补丁现有的核心类时。 我认为范围类是一个很好的候选者,可以使用夹紧方法

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

(min..max).clamp(v)

或者普通的数组对象。我不喜欢这个,因为clamp函数仅适用于三个元素的数组。

class Array
    def clamp
      sort[1]
    end
end

你可以这样调用:

[a,x,b].clamp

调用clamp函数来处理数组或范围似乎非常令人困惑。这不是任何人会想到的结果。在我看来,对数字或可比较对象进行猴子补丁似乎更容易理解。 - Ulysse BN

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接