遅延的な取得とフィルタリング
無限ストリームを切り取ります。
「遅延的な取得とフィルタリング」はCoddyKit上の無料Scala for Backend Engineering & Functional Programmingレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはScala for Backend Engineering & Functional Programming学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Scala for Backend Engineering & Functional Programmingコースには全4レッスンが含まれています。
遅延したまま消費する
LazyListの真価は、消費するときに現れます。take、filter、mapなどの操作は遅延性を保ち、最終的に強制評価されるセルだけを計算します。
このレッスンでは、主要な変換処理と、適切なタイミングで遅延評価を止める方法を扱います。
take(n)
take(n)は、先頭から最大n個の要素を含むLazyListを返します。このLazyList自体も遅延しています。結果を強制評価するまで、何も計算されません。
無限ストリームの範囲を安全に制限する方法です。
object Demo extends App {
val first5 = LazyList.from(1).take(5)
println(first5.toList)
}takeWhile
takeWhile(p)は、述語が真である間は要素を返し、最初に偽になった時点で停止します。
無限ストリームでは、要素数をあらかじめ知る必要がない、明確な停止条件になります。
object Demo extends App {
val small = LazyList.from(1).takeWhile(_ < 6)
println(small.toList)
}dropとdropWhile
drop(n)は先頭のn個の要素をスキップし、dropWhile(p)は述語が真である間スキップします。どちらも遅延した残りの部分を返します。
ストリーム内の位置を移動してから、一部を取得するときに使用します。
object Demo extends App {
val rest = LazyList.from(1).drop(3).take(3)
println(rest.toList)
}遅延フィルタリング
LazyListに対するfilterは遅延します。下流のコンシューマーが要素を要求したときにだけ、その要素をテストします。
takeと組み合わせると、要求を満たすのに必要な分だけ元の要素を処理し、それ以上は処理しません。
object Demo extends App {
val evens = LazyList.from(1).filter(_ % 2 == 0)
println(evens.take(4).toList)
}要求を確認する
述語の中に出力処理を追加して、実際にテストされる要素がどれほど少ないかを確認してみましょう。フィルタは、takeの要求が満たされるまでしか実行されません。
これを実行してください。「check」行の数から、ストリーム全体ではなく、要求に応じて評価されていることが分かります。
object Demo extends App {
val r = LazyList.from(1).filter { n =>
println("check " + n); n % 3 == 0
}
println(r.take(2).toList)
}mapとfilterの連結
変換処理は連結できます。パイプライン全体が遅延したまま、要素ごとに融合されます。元の各要素は、要求されたときにだけmap、次にfilterを通過します。
途中で完全なコレクションが作られることはありません。
object Demo extends App {
val r = LazyList.from(1).map(_ * _).filter(_ > 10).take(3)
println(r.toList)
}find:早期停止
find(p)は、最初に一致した要素をOptionとして返し、その要素に到達するまでだけ強制評価します。無限ストリームの検索に最適です。
一致する要素が見つかると、評価は直ちに停止します。
object Demo extends App {
val firstBig = LazyList.from(1).find(_ * _ > 50)
println(firstBig)
}headOptionとexists
headOptionは先頭の要素を安全に確認します。exists(p)は一致する要素が見つかるまでだけ強制評価します(一致しない場合は永遠に続きます)。無限ストリームでexistsを使うのは、一致する要素が必ず存在するときだけにしてください。
どちらも可能な限り早く停止します。
object Demo extends App {
val has = LazyList.from(1).exists(_ == 7)
println(has)
}結果を強制評価する
遅延変換処理は実行する作業を記述し、終端操作がその処理を強制評価します。toList、foreach、sum、foldLeftは、(範囲を制限した)ストリームを消費して具体的な値を生成します。
ストリーム全体を必要とする終端操作の前には、必ず無限ストリームの範囲を制限してください。
object Demo extends App {
val total = LazyList.from(1).take(100).sum
println(total)
}フィルタリング時の注意点
何にも一致しないfilterを使うと、範囲を制限したtakeが無限検索に変わってしまいます。LazyList.from(1).filter(_ < 0).take(1)は永久に停止しません。
述語を満たす要素が存在し得ることを確認するか、takeWhileと組み合わせて必ず終了するようにしてください。
確認問題
遅延したまま消費する仕組みについて理解度を確認しましょう。
まとめ
take、takeWhile、drop、filter、mapは遅延性を保ち、要素ごとに融合されます。find、exists、headOptionは早期に停止し、toListやsumなどの終端操作は結果を強制評価します。
無限ストリームでは、満たせない条件のフィルタに注意してください。これで、遅延シーケンスを安心して生成・消費できるようになりました。
よくある質問
「遅延的な取得とフィルタリング」レッスンは無料ですか?
はい。「遅延的な取得とフィルタリング」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Scala for Backend Engineering & Functional Programmingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Scala for Backend Engineering & Functional Programmingコースには全4レッスンが含まれています。
「遅延的な取得とフィルタリング」で何を学びますか?
無限ストリームを切り取ります。 ブラウザで直接実行するハンズオンコードでScala for Backend Engineering & Functional Programmingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Scala for Backend Engineering & Functional Programmingを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのScala for Backend Engineering & Functional Programmingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「遅延的な取得とフィルタリング」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このScala for Backend Engineering & Functional Programmingレッスンでコードを書いて実行できますか?
はい。すべてのScala for Backend Engineering & Functional Programmingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 遅延評価の仕組み
- LazyListを構築する
- 無限ストリーム
- 遅延的な取得とフィルタリング