0Pricing
Ruby Academy · レッスン

遅延 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 result

take と 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_match

lazy を使う場面

次のような場合は 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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. カスタム each の記述
  2. Enumerable のインクルード
  3. 遅延 Enumerator
  4. Enumerator オブジェクト
← Ruby Academyに戻る