为Ruby中的Numerics优化这种“Boundarize”方法

时间:2010-05-25 04:30:17

标签: ruby optimization numbers

由于缺乏更好的名字,我用一种叫做“Boundarize”的方法扩展Numerics;我确信实际上有真正的名字。但其基本目的是将给定点重置为边界内。

即围绕边界“包裹”一个点;如果该区域在0和100之间,如果该点变为-1:

-1.boundarize(0,100)        # => 99 

(从一个太远到负面“包裹”点到最大值的一个)。

102.boundarize(0,100)       # => 2

这是一个非常简单的实现功能;当数字低于最小值时,只需添加(max-min)直到它在边界内。如果数字高于最大值,则简单地减去(max-min)直到它在边界内。

我还需要考虑的一点是,在某些情况下,我不希望在范围中包含最小值,以及我不希望在范围中包含最大值的情况。这被指定为参数。

但是,我担心我目前的实施非常可怕,非常低效。并且因为每次屏幕上的某些东西移动,它都必须重新运行它,这是我的应用程序的瓶颈之一。有人有什么想法吗?

module Boundarizer

  def boundarize min=0,max=1,allow_min=true,allow_max=false 

    raise "Improper boundaries #{min}/#{max}" if min >= max
    raise "Cannot have two closed endpoints" if not (allow_min or allow_max)

    new_num = self

    if allow_min
      while new_num < min
        new_num += (max-min)
      end
    else
      while new_num <= min
        new_num += (max-min)
      end
    end

    if allow_max
      while new_num > max
        new_num -= (max-min)
      end
    else
      while new_num >= max
        new_num -= (max-min)
      end
    end

    return new_num

  end

end

class Numeric
  include Boundarizer
end

0.boundarize(10,50)             # => 40
10.boundarize(0,10)             # => 0     (the maximum is by default not allowed)
0.boundarize(0,20,false)        # => 20    (the minimum is not allowed)

2 个答案:

答案 0 :(得分:2)

在我看来,你所需要的只是模数(%运算符),并有几个额外的检查来处理allow_min和allow_max:

irb(main):002:0> -1 % 100
=> 99
irb(main):003:0> -101 % 100
=> 99
irb(main):004:0> 102 % 100
=> 2

答案 1 :(得分:0)

您的操作几乎是模运算see here

Ruby为此提供了运算符%。