【问题标题】:Comma separated list with Enumerator带枚举器的逗号分隔列表
【发布时间】:2014-03-24 18:54:40
【问题描述】:

我刚刚开始在我的新项目(Scala 2.10.3、Play2 2.2.1、Reactivemongo 0.10.0)中使用 Scala,并遇到了一个非常标准的用例,即 - 将 MongoDB 中的所有用户流式传输到外部客户。在导航 Enumerator, Enumeratee API 之后,我还没有找到一个可靠的解决方案,所以我通过以下方式解决了这个问题:

    val users = collection.find(Json.obj()).cursor[User].enumerate(Integer.MAX_VALUE, false)
    var first:Boolean = true
    val indexedUsers = (users.map(u => {
        if(first) {
            first = false;
            Json.stringify(Json.toJson(u))
        } else {
            "," + Json.stringify(Json.toJson(u))
        }
    }))

在我看来,这有点棘手 - 主要是因为我需要在元素列表中添加 Json Start Array、Json End Array 和逗号分隔符,而我无法将其作为纯 Json 流提供,所以我将其转换为 String steam。

使用 reactivemongo 的标准解决方案是什么?

【问题讨论】:

    标签: json scala playframework-2.0 reactivemongo


    【解决方案1】:

    我写了一个辅助函数来完成你想要实现的目标:

    def intersperse[E](e: E, enum: Enumerator[E]): Enumerator[E] = new Enumerator[E] {
      val element = Input.El(e)
    
      override def apply[A](i1: Iteratee[E, A]): Future[Iteratee[E, A]] = {
        var iter = i1
    
        val loop: Iteratee[E, Unit] = {
          lazy val contStep = Cont(step)
    
          def step(in: Input[E]): Iteratee[E, Unit] = in match {
            case Input.Empty ⇒ contStep
            case Input.EOF ⇒ Done((), Input.Empty)
            case e @ Input.El(_) ⇒
              iter = Iteratee.flatten(iter.feed(element).flatMap(_.feed(e)))
              contStep
          }
    
          lazy val contFirst = Cont(firstStep)
    
          def firstStep(in: Input[E]): Iteratee[E, Unit] = in match {
            case Input.EOF ⇒ Done((), Input.Empty)
            case Input.Empty ⇒
              iter = Iteratee.flatten(iter.feed(in))
              contFirst
            case Input.El(x) ⇒
              iter = Iteratee.flatten(iter.feed(in))
              contStep
          }
    
          contFirst
        }
    
        enum(loop).map { _ ⇒ iter }
      }
    }
    

    用法:

    val prefix = Enumerator("[")
    val suffix = Enumerator("]")
    val asStrings = Enumeratee.map[User] { u => Json.stringify(Json.toJson(u)) }
    val result = prefix >>> intersperse(",", users &> asStrings) >>> suffix
    
    Ok.chunked(result)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多