如何在scala中收集分页结果
我试图通过尝试在Scala中执行以下逻辑来收集分页结果,但不幸失败:如何在scala中收集分页结果,scala,pagination,Scala,Pagination,我试图通过尝试在Scala中执行以下逻辑来收集分页结果,但不幸失败: def python_version(): cursor books, cursor = fetch_results() while (cursor!=null) { new_books = fetch_results(cursor) books = books + new_books } return books def fetch_results
def python_version():
cursor
books, cursor = fetch_results()
while (cursor!=null) {
new_books = fetch_results(cursor)
books = books + new_books
}
return books
def fetch_results(cursor=None):
#do some fetchings...
return books, next_cursor
也许是这样的:
Iterator.iterate(fetch_results()) {
case (_, None) => (Nil, None)
case (books, cursor) => fetch_results(cursor)
}.map(_._1).takeWhile(_.nonEmpty).flatten.toList`
.iterate
将第一个参数作为迭代器的初始元素,第二个参数是一个函数,给定前一个元素,该函数计算下一个元素。
因此,这将创建一个元组迭代器(Seq[Book],Cursor)
,从最初返回的fetch\u results
开始,然后继续获取更多结果,并将其累加,直到nextCursor
为None
(我使用了None
而不是null,因为null是邪恶的,不应该在正常语言中使用,比如scala,它提供了足够的工具来避免它们)
然后,.map(u._1)
丢弃游标(不再需要它们),因此我们现在有了一个页面迭代器,.takeWhile
首先截断迭代器
页面为空,然后将所有内部
序列连接在一起,最后toList
具体化所有元素,并返回整个图书列表。这里有一个使用递归函数的替代解决方案,它避免了可变值:
def fetchResults(c: Option[Cursor]=None): (List[Book], Option[Cursor]) = ...
def fetchAllResults(): List[Book] = {
@tailrec
def loop(cursor: Option[Cursor], res: List[Book]): List[Book] = {
val (books, newCursor) = fetchResults(cursor)
val newBooks = res ::: books
newCursor match {
case Some(_) =>
loop(newCursor, newBooks)
case None =>
newBooks
}
}
loop(None, Nil)
}
这是Scala中递归函数的一个相当标准的模式,实际递归在内部函数中完成。上一次迭代的结果被传递到下一次迭代,然后从函数返回。这意味着循环
是一个尾部递归函数,可以由编译器优化为<代码>while
循环。(如果这不是尾部递归,则@tailrec
注释告诉编译器发出警告)