問題タブ [scala-streams]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
1 に答える
337 参照

scala - Scalaの遅延ページネーション(イテレータのストリーム/イテレータ?)

への呼び出しを介して、データベース API から一度に 1 ページずつ (ページあたりのレコード数が不明な状態で) 非常に多数のレコードを順番に読み取っています。def readPage(pageNumber: Int): Iterator[Record]

私は、この APIをページの無限ストリームStream[Iterator[Record]]またはIterator[Iterator[Record]]イテレータのシーケンスとして扱い、抽象化して、クライアントからのページネーション。クライアントは next() を呼び出すことで結果を繰り返すことができ、次のページ (Iterator[Record]) を取得します。

これを Scala で実装する最も慣用的で効率的な方法は何ですか。

編集:一度に1ページずつレコードをフェッチして処理する必要があり、メモリ内のすべてのページからすべてのレコードを維持することはできません。1 つのページが失敗した場合は、例外をスローします。多数のページ/レコードは、すべての実用的な目的において無限であることを意味します。ページの無限ストリーム (またはイテレータ) として扱いたいと思います。各ページは有限数のレコードのイテレータです (たとえば、<1000 未満ですが、時間がある場合は正確な数は不明です)。

Monixで BatchCursorを見ましたが、別の目的を果たします。

編集 2: これは、以下の Tomer の回答を出発点として使用する現在のバージョンですが、Iterator の代わりに Stream を使用しています。これにより、 https://stackoverflow.com/a/10525539/165130に従って末尾再帰の必要性を排除し、ストリームのプリペンド#::操作に O(1) 時間を持つことができます (操作を介してイテレータを連結した場合は++O になります) (n))

注: ストリームは遅延評価されますが、ストリームのメモ化は依然としてメモリの爆発を引き起こす可能性があり、メモリ管理はトリッキーになります。以下のストリームを定義するためにからvalに変更しても、何の効果もないようですdefdef pages = readAllPages

編集 3: Tomer による 2 番目の提案が最良のようです。その実行時間とメモリ フットプリントは上記のソリューションに似ていますが、はるかに簡潔でエラーが発生しやすくなっています。

注: Stream.from(1)1 から開始して 1 ずつ増加するストリームを作成します。これはAPI ドキュメントにあります。