遅延 Enumerator
遅延評価です。
「遅延 Enumerator」はCoddyKit上の無料Ruby Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはRuby Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Ruby Academyコースには全4レッスンが含まれています。
遅延評価
通常、Enumerableのメソッドはコレクション全体を一度に処理します。一方、遅延 Enumerator は必要になったときだけ要素を1つずつ処理します。これにより、非常に大きなシーケンスや無限シーケンスも扱えます。
result = (1..Float::INFINITY).lazy.map { |n| n * 2 }.first(5)
p result即時評価メソッドの問題
無限範囲に対してlazyなしでmapを呼び出すと、完全な結果配列を先に作成しようとするため、処理が終わりません。
# Eager version would hang. Lazy completes instantly:
first_three = (1..Float::INFINITY).lazy.select(&:even?).first(3)
p first_three遅延 Enumerator を作成する
任意の Enumerable に対して.lazyを呼び出すと、遅延版を取得できます。その後チェーンしたメソッドも遅延処理になります。
lazy = (1..10).lazy
puts lazy.class強制するまで何も実行されない
遅延チェーンは処理手順を構築するだけで、実行はしません。first、to_a、forceなどの終端メソッドが処理を開始します。
chain = (1..Float::INFINITY).lazy.map { |n| n * n }
puts "Nothing computed yet"
p chain.first(4)結果を強制的に取得する
force(別名はto_a)は、上限のある遅延チェーンを配列として実体化します。
result = (1..20).lazy.select(&:odd?).first(5)
p result
all = (1..6).lazy.map { |n| n * 10 }.force
p all遅延処理をチェーンする
複数の遅延操作は、コレクション全体を別々に何度も処理するのではなく、要素ごとに交互に処理されます。次の要素に進む前に、各値がチェーン全体を通過します。
result = (1..Float::INFINITY)
.lazy
.map { |n| n * n }
.select { |n| n.even? }
.first(4)
p resulttake と take_while
遅延処理のtakeとtake_whileは、条件を満たした時点で値の取得を停止します。
result = (1..Float::INFINITY).lazy.take_while { |n| n < 6 }.to_a
p result無限シーケンス
遅延 Enumerator はジェネレーターで特に力を発揮します。Enumeratorと組み合わせると、終わりのないストリームを表現できます。
naturals = Enumerator.new do |y|
n = 1
loop { y << n; n += 1 }
end
p naturals.lazy.map { |x| x * 3 }.first(5)メモリ効率
遅延チェーンは中間コレクション全体を実体化しないため、大量のデータを少数の結果に絞り込む場合にメモリを節約できます。
big = (1..1_000_000).lazy
first_match = big.select { |n| n % 7 == 0 && n % 11 == 0 }.first
puts first_matchlazy を使う場面
次のような場合は lazy を使います。
- 入力が無限、または非常に大きい場合
- 必要な結果が少数の場合
- 大きな中間配列を避けたい場合
小さなコレクションでは、即時評価メソッドのほうが簡単で十分に高速です。
fizz = (1..Float::INFINITY).lazy.select { |n| n % 3 == 0 }.first(5)
p fizzまとめ
遅延 Enumerator は処理を後回しにします。
.lazyによってチェーンが遅延処理になります。- 終端メソッドが値を取得したときだけ処理が実行されます。
- 無限シーケンスや非常に大きなシーケンスに最適です。
squares = (1..Float::INFINITY).lazy.map { |n| n * n }
p squares.select(&:odd?).first(4)確認
遅延 Enumerator についての理解度を確認しましょう。
振り返り
遅延 Enumerator について学びました。
.lazyは計算を後回しにします。- 終端メソッド(
first、to_a、force)が処理を開始します。 - 要求されたときに、各値がチェーン全体を通過します。
- 無限シーケンスや大きなシーケンスに適しています。
p (1..Float::INFINITY).lazy.select(&:even?).map { |n| n + 1 }.first(3)よくある質問
「遅延 Enumerator」レッスンは無料ですか?
はい。「遅延 Enumerator」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Ruby Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Ruby Academyコースには全4レッスンが含まれています。
「遅延 Enumerator」で何を学びますか?
遅延評価です。 ブラウザで直接実行するハンズオンコードでRuby Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Ruby Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのRuby Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「遅延 Enumerator」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このRuby Academyレッスンでコードを書いて実行できますか?
はい。すべてのRuby Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- カスタム each の記述
- Enumerable のインクルード
- 遅延 Enumerator
- Enumerator オブジェクト