由于缺乏更好的名字,我用一种叫做“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)
答案 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为此提供了运算符%。