Как бы вы написали этот код C # (который использует ключевое слово yield) лаконично на Ruby? - PullRequest
1 голос
/ 21 апреля 2010

Есть ли хороший способ эмулировать yield в Ruby? Я заинтересован в написании аналогичной «бесконечной последовательности фибов» в Ruby.

Вот код:

using System;
using System.Collections.Generic;
using System.Linq;


namespace cs2 {
    class Program {
        static void Main(string[] args) {          
          var i=Fibs().TakeWhile(x=>x < 1000).Where(x=>x % 2==0).Sum();
        }

        static IEnumerable<long> Fibs() {
            long a = 0, b = 1;
            while (true) {
                yield return b;
                b += a;
                a = b - a;
            }
        }
    }
}

Если это возможно, приведите пример.

Ответы [ 2 ]

10 голосов
/ 21 апреля 2010

Распространенная идиома в ruby ​​для реализации таких последовательностей заключается в определении метода, который выполняет блок для каждого элемента в последовательности, если он задан, или возвращает перечислитель, если это не так. Это будет выглядеть так:

def fibs
  return enum_for(:fibs) unless block_given?
  a = 0
  b = 1
  while true
    yield b
    b += a
    a = b - a
  end
end

fibs
#=> #<Enumerable::Enumerator:0x7f030eb37988>
fibs.first(20)
#=> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]
fibs.take_while {|x| x < 1000}.select {|x| x%2 == 0}
#=> [2, 8, 34, 144, 610]
fibs.take_while {|x| x < 1000}.select {|x| x%2 == 0}.inject(:+)
=> 798
2 голосов
/ 21 апреля 2010

числа Фибоначчи с волокнами Руби 1.9 :

fib = Fiber.new do 
  x, y = 0, 1
  loop do 
    Fiber.yield y
    x,y = y,x+y
  end
end

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