1

I have a function that is attempting to build a JSON object containing a representation of multiple tuples that are stored in a Seq[A], where A is a (Loop, Option[User]). My code looks like so:

def loops = Action {
    val page : Int = 1
    val orderBy : Int = 1
    val filter : String = ""
    val jsonifyLoops : (Loop, Option[User]) => Map[String, String] = { 
      case (loop,user) =>
            Map(
                "name" -> loop.name,
                "created_at" -> loop.createdAt.map(dateFormat.format).getOrElse(""),
                "deleted_at" -> loop.deletedAt.map(dateFormat.format).getOrElse(""),
                "user_name" -> user.map(_.name).getOrElse("")
            )
    }
    Ok(toJson(Map(
        "loops" -> toJson(
            Loop.list( page = page, orderBy = orderBy, filter = ("%"+filter+"%") )
                .items.map( jsonifyLoops )
            )
        )
    ))
}

Loops.list produces a Page[A], from the helper class below:

case class Page[A](items: Seq[A], page: Int, offset: Long, total: Long) {
    lazy val prev = Option(page - 1).filter(_ >= 0)
    lazy val next = Option(page + 1).filter(_ => (offset + items.size) < total)
}

Thus, Loops.list(...).items should get me a Seq[(Loop, Option[User])], onto which I should be able to apply a map function. I've defined my jsonifyLoops function to have what I think is the appropriate prototype, but I must be doing something wrong, because the compiler throws me the following error:

    [error] [...] Application.scala:42: type mismatch;
    [error]  found   : (models.Loop, Option[models.User]) => Map[String,String]
    [error]  required: (models.Loop, Option[models.User]) => ?
    [error]                     .items.map( jsonifyLoops )
    [error]                                 ^

What am I doing wrong?

4

2 回答 2

2

您的函数jsonifyLoops有两个参数: aLoop和 an Option[User]。但是, 的成员items是类型的元组(Loop, Option[User]),因此items.map需要一个接受该元组的参数的函数作为参数。因此,您需要将jsonifyLoops二进制函数转换为带有一对参数的一元函数;Function2#tupled将为您执行此操作:

scala> :t jsonifyLoops
(Loop, Option[User]) => Map[String,String]
scala> :t jsonifyLoops.tupled
((Loop, Option[User])) => Map[String,String]

你会这样使用它:

Loop.list(page = page, orderBy = orderBy, filter = ("%"+filter+"%"))
    .items.map(jsonifyLoops.tupled)
于 2013-07-30T01:43:58.027 回答
1

您需要在 jasonifyLoops 中为模式匹配添加默认情况。在没有默认案例的情况下,如果您的案例陈述失败,您将返回一个单元。所以这样的事情应该有效:

val jsonifyLoops : (Loop, Option[User]) => Map[String, String] = { 
  case (loop,user) =>
        Map(
            "name" -> loop.name,
            "created_at" -> loop.createdAt.map(dateFormat.format).getOrElse(""),
            "deleted_at" -> loop.deletedAt.map(dateFormat.format).getOrElse(""),
            "user_name" -> user.map(_.name).getOrElse("")
        )
  case _ => Map[String, String]()
}

这只是说如果输入不匹配,则返回一个空 Map。但是,您应该将其替换为您想要对默认情况执行的任何处理。

于 2013-07-29T01:10:52.543 回答