Делайте что-то бесконечно много раз с индексом - PullRequest
16 голосов
/ 01 марта 2012

В более рубиновый способ выполнения проекта euler # 2 , часть кода

while((v = fib(i)) < 4_000_000)
  s+=v if v%2==0
  i+=1
end

Есть ли способ изменить i += 1 на более функциональную конструкцию в стиле программирования?

Лучшее, что я могу придумать, это

Float::MAX.to_i.times do |i|
  v = fib(i)
  break unless v < 4_000_000
  s += v if v%2==0
end

потому что вы не можете позвонить .times на число с плавающей запятой.

Ответы [ 3 ]

16 голосов
/ 05 октября 2015

Numeric.step имеет параметры по умолчанию бесконечности (предел) и 1 (размер шага).

1.step do |i|
  #...
end

Ради интереса, вы можете попробовать

1.step.size
10 голосов
/ 01 марта 2012

Есть предопределенная (в 1.9.2) константа Float::INFINITY, поэтому вы можете написать

1.upto(Float::INFINITY) do |i|
  ...
end

(Вы также можете использовать Enumerator и take_while, выворачивая проблему наизнанку, чтобыэто больше похоже на Haskell или Python, но take_while является жадным и создает массив.)

3 голосов
/ 01 февраля 2019

Ruby 2.5 представил открытый диапазон:

(1..).each do |i|
  #...
end
...