2010-05-25 5 views
0

J'étend Numerics avec une méthode que j'appelle "Boundarize" par manque de meilleur nom; Je suis sûr qu'il y a de vrais noms pour ça. Mais son but fondamental est de réinitialiser un point donné pour être dans une limite. C'est-à-dire "envelopper" un point autour de la limite; si la zone est betweeon 0 et 100, si le point va à -1:Optimisation de cette méthode "Boundarize" pour Numerics en Ruby

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

(aller trop loin l'un à la borne négative « enroule » autour de la pointe de l'un de l'max).

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

C'est une fonction très simple à mettre en œuvre; lorsque le nombre est inférieur au minimum, ajoutez simplement (max-min) jusqu'à ce qu'il se trouve dans la limite. Si le nombre est supérieur au maximum, il suffit de soustraire (max-min) jusqu'à ce qu'il soit dans la limite. Une chose dont je dois également tenir compte est qu'il y a des cas où je ne veux pas inclure le minimum dans la gamme, et des cas où je ne veux pas inclure le maximum dans la gamme. Ceci est spécifié en tant qu'argument. Cependant, je crains que ma mise en œuvre actuelle soit horriblement, terriblement, très inefficace. Et parce que chaque fois que quelque chose bouge à l'écran, il faut le relancer, c'est l'un des goulets d'étranglement de mon application. Quelqu'un a des idées?

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) 

Répondre

2

Il me semble que tout ce que vous avez besoin est modulo (% opérateur) avec un couple de contrôles supplémentaires pour gérer allow_min et allow_max:

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

merde sainte, modulo. Je suis stupide. –

0

votre opération est à peu près l'opération modulo see here. Ruby fournit l'opérateur% pour cela.

Questions connexes