質問「yieldという言葉の意味Enumerator::Yielder#yield
」は、その方法に言及しています。使ったことがないので、どんな場面で役立つのだろう。
エラトステネスのふるいなど、項目の無限リストを作成する場合や、外部イテレータを使用する必要がある場合に、主に役立ちますか?
質問「yieldという言葉の意味Enumerator::Yielder#yield
」は、その方法に言及しています。使ったことがないので、どんな場面で役立つのだろう。
エラトステネスのふるいなど、項目の無限リストを作成する場合や、外部イテレータを使用する必要がある場合に、主に役立ちますか?
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
、あなたの質問とリンクされた質問に刺激されて、これが私が思いついたものです.
列挙したいオブジェクトが複数ある場合に便利なようですが、 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