如何将一组页面作为Stream获取?

时间:2013-09-18 05:29:20

标签: scala

如何使用将页面作为项目流返回的服务?

例如,Amazon S3允许您从前一个对象列表中获取初始对象列表或下一个对象列表。

例如,请考虑模拟此类行为的代码:

import math._

case class Page(number: Int)

case class Pages(pages: Seq[Page], truncated: Boolean)

class PagesService(pageSize: Int, pagesServed: Int) {
  def getPages =
    Pages((1 to pageSize).map(Page), pageSize < pagesServed)

  def nextPages(previous: Pages) = {
    val first = previous.pages.last.number + 1
    val last = min(first + pageSize, pagesServed)
    Pages((first to last).map(Page), last < pagesServed)
  }
}

object PagesClient extends App {
  val service = new PagesService(10, 100)

  val first = service.getPages
  assert(first.truncated)
  first.pages.foreach(println(_))

  val second = service.nextPages(first)
  second.pages.foreach(println(_))

  val book: Stream[Page] = ???
}

我怎么能写出最后一个表达式?

2 个答案:

答案 0 :(得分:2)

val book: Stream[Pages] = first #:: book.map(service.nextPages).takeWhile(_.pages.nonEmpty)
val pages: Stream[Page] = book.flatten(_.pages)

答案 1 :(得分:1)

我不知道这是不是一个错字。如果您的意思是Stream[Pages],那很简单:

val book: Stream[Pages] = first #:: book.map(x => service.nextPages(x))

如果您的意思是Stream[Page],即来自所有网页的Page流,那么:

val first = service.getPages
val second = service.nextPages(first)

val books: Stream[Page] = {
  val currentPages = book.iterator
  val firstPages = currentPages.next.pages.iterator

  def inner(current: Iterator[Page]): Stream[Page] = {
    if (current.hasNext) {
      current.next #:: inner(current)
    } else {
      val i = currentPages.next
      inner(i.pages.iterator)
    }
  }
  inner(firstPages);
}

以上基本上需要Pages,作为流的一部分返回其Page。如果Pages用尽,则转到下一个Pages,依此类推。