2014-03-06 23 views
1

鑑於以下case class ...播放與JSON:如何使Scala代碼更簡潔

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

...我需要取決於是否name被定義爲產生不同的JSON:

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

您可以使用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)) 
    )) 
}