Play& JSON:如何使scala代码更简洁

时间:2014-03-06 21:32:00

标签: json scala playframework

鉴于以下case class ...

case class Address(
  name: Option[String],
  zip: String,
  city: String
)

...我需要生成不同的JSON,具体取决于是否定义了name

val selector = address.name.map { addressName =>
  Json.obj(
    userId.key -> userId.value,
    "addresses.name" -> name,
    "$or" -> Json.arr(
      Json.obj(s"addresses.name" -> name),
      Json.obj("addresses.name" -> Json.obj("$ne" -> addressName))
    )
  )
} getOrElse {
  Json.obj(
    userId.key -> userId.value,
    "addresses.name" -> name
  )
}

如果查看上面的代码,两个块都有一个共同的部分:

Json.obj(
  userId.key -> userId.value,
  "addresses.name" -> name

有没有办法让代码更简洁而不重复公共部分?

1 个答案:

答案 0 :(得分:1)

您可以使用JsObject上的两种方法:++ or +。第一个与另一个JsObject合并,第二个添加一个新字段。

val commonPart = Json.obj(
  userId.key -> userId.value,
  "addresses.name" -> name
)
val selector = address.name.map { addressName =>
  commonPart + "$or" -> Json.arr(
    Json.obj(s"addresses.name" -> name),
    Json.obj("addresses.name" -> Json.obj("$ne" -> addressName))
  )
} getOrElse(commonPart)

使用foldLeft:

val selector = address.name.foldLeft(Json.obj(userId.key -> userId.value, "addresses.name" -> name)) {
  (commonPart, addressName) =>
    commonPart + ("$or" -> Json.arr(
      Json.obj(s"addresses.name" -> name),
      Json.obj("addresses.name" -> Json.obj("$ne" -> addressName))
    ))
}