14

質問「yieldという言葉の意味Enumerator::Yielder#yield」は、その方法に言及しています。使ったことがないので、どんな場面で役立つのだろう。

エラトステネスのふるいなど、項目の無限リストを作成する場合や、外部イテレータを使用する必要がある場合に、主に役立ちますか?

4

4 に答える 4

1

Mladen が他の回答を得たと述べたので、複数の物理デバイスからデータを受信し、データを分析し、関連するデータ (複数のデバイスから表示される) を接続するアプリケーションを作成するときに、今日私が行ったばかりのことの例を挙げたいと思いました。 . これは長時間実行されるアプリケーションであり、データを破棄しなければ (たとえば、少なくとも 1 日前の更新がない場合)、データは無限に大きくなります。

以前は、次のようなことをしていました。

delete_old_stuff if rand(300) == 0

乱数を使用してこれを達成します。ただし、これは純粋に決定論的ではありません。およそ 300 回の評価 (つまり、秒) ごとに実行されることはわかっていますが、正確に 300 回ごとに実行されるわけではありません。

以前書いたものはこんな感じです。

counter = Enumerator.new do |y|
  a = (0..300)
  loop do
    a.each do |b|
      y.yield b
    end
    delete_old_stuff
  end
end

delete_old_stuff if rand(300) == 0そして私はと置き換えることができますcounter.next

さて、これを行うためのより効率的な方法または事前に作成された方法があると確信していますがEnumerator::Yielder#yield、あなたの質問とリンクされた質問に刺激されて、これが私が思いついたものです.

于 2011-02-26T20:40:08.153 に答える
0

列挙したいオブジェクトが複数ある場合に便利なようですが、 flat_map は適切ではなく、列挙を別のアクションに連鎖させたい場合:

module Enumerable
  def count_by
    items_grouped_by_criteria = group_by {|object| yield object}
    counts = items_grouped_by_criteria.map{|key, array| [key, array.length]}
    Hash[counts]
  end
end

def calculate_letter_frequencies
  each_letter.count_by {|letter| letter}
end

def each_letter
  filenames = ["doc/Quickstart", "doc/Coding style"]
  # Joining the text of each file into a single string would be memory-intensive
  enumerator = Enumerator.new do |yielder|
    filenames.each do |filename|
      text = File.read(filename)
      text.chars.each {|letter| yielder.yield(letter)}
    end
  end
  enumerator
end

calculate_letter_frequencies
于 2012-03-28T01:26:18.937 に答える