Оптимизация этого метода Boundarize для чисел в Ruby - PullRequest
0 голосов
/ 25 мая 2010

Я расширяю Numerics методом, который я называю "Boundarize" из-за отсутствия лучшего имени; Я уверен, что для этого есть настоящие имена. Но его основная цель - сбросить заданную точку, чтобы она находилась в пределах границы.

То есть, «оборачивая» точку вокруг границы; если область между 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 ]

2 голосов
/ 25 мая 2010

Мне кажется, все, что вам нужно, это по модулю (оператор%) с парой дополнительных проверок для обработки 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
0 голосов
/ 25 мая 2010

ваша операция в значительной степени является операцией по модулю см. Здесь .

Ruby предоставляет оператор% для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...