使用 play-json 转换器创建并填充 JsArray
Create and fill a JsArray with play-json transformer
使用Play/Scala,我尝试将此json转换为:
val json = Json.parse("""
{
"name": "John Doe",
"location": {
"lon": 48.858596,
"lat": 2.294481
}
}
""")
进入这个结果:
val result = Json.parse("""
{
"name": "John Doe",
"location": {
"type": "Point",
"coordinates": [48.858596, 2.294481]
}
}
""")
知道如何应用魔法吗?这是我尝试过的:
import play.api.libs.json._
import play.api.libs.json.Reads._
import play.api.libs.functional.syntax._
val transformer = {
val locationField = __ \ "location"
val lon = (locationField \ "lon").json.pick
val lat = (locationField \ "lat").json.pick
__.json.update((
(locationField \ "type").json.put( JsString("Point") ) and
(locationField \ "coordinates").json.put( JsArray() )).reduce
andThen
(locationField \ "coordinates").json.update(of[JsArray].map { // How to add lon/lat into JsArray?????
case JsArray(arr) => JsArray(arr :+ JsNumber(3L))
}
)
andThen (
(locationField \ "lon").json.prune and
(locationField \ "lat").json.prune).reduce
)
}
json.transform(transformer)
在此处获取代码:https://gist.github.com/chrissom/20c5aa254210d7c32f53479df6a66f68
假设导入:
import play.api.libs.json._
您可以定义代表 location
值的 Location
。
case class Location(lon: Double, lat: Double) {
def toPoint: JsObject = {
Json.obj(
"type" -> "Point",
"coordinates" -> Json.arr(lon, lat)
)
}
}
object Location {
implicit val reads: Reads[Location] = Json.reads[LonLat]
}
现在你可以做:
val locationJson = Json.parse("""{"lon": 48.858596, "lat": 2.294481}""")
locationJson.transform(of[LonLat].map(_.toPoint))
// Output:
// JsSuccess({"type":"Point","coordinates":[48.858596,2.294481]},)
现在您可以将其插入转换中,例如:
(__ \ 'location).json.update(of[LonLat].map(_.toPoint))
但是在此转换中,您将剩下 lat
和 lon
字段。所以删除它们:
(__ \ 'location).json.update(of[LonLat].map(_.toPoint)) andThen
(__ \ 'location \ 'lat).json.prune andThen
(__ \ 'location \ 'lon).json.prune
在我看来,不可能将其简化,因为 update
是同类中唯一的操作 - 恰好是 deep-merge.
使用Play/Scala,我尝试将此json转换为:
val json = Json.parse("""
{
"name": "John Doe",
"location": {
"lon": 48.858596,
"lat": 2.294481
}
}
""")
进入这个结果:
val result = Json.parse("""
{
"name": "John Doe",
"location": {
"type": "Point",
"coordinates": [48.858596, 2.294481]
}
}
""")
知道如何应用魔法吗?这是我尝试过的:
import play.api.libs.json._
import play.api.libs.json.Reads._
import play.api.libs.functional.syntax._
val transformer = {
val locationField = __ \ "location"
val lon = (locationField \ "lon").json.pick
val lat = (locationField \ "lat").json.pick
__.json.update((
(locationField \ "type").json.put( JsString("Point") ) and
(locationField \ "coordinates").json.put( JsArray() )).reduce
andThen
(locationField \ "coordinates").json.update(of[JsArray].map { // How to add lon/lat into JsArray?????
case JsArray(arr) => JsArray(arr :+ JsNumber(3L))
}
)
andThen (
(locationField \ "lon").json.prune and
(locationField \ "lat").json.prune).reduce
)
}
json.transform(transformer)
在此处获取代码:https://gist.github.com/chrissom/20c5aa254210d7c32f53479df6a66f68
假设导入:
import play.api.libs.json._
您可以定义代表 location
值的 Location
。
case class Location(lon: Double, lat: Double) {
def toPoint: JsObject = {
Json.obj(
"type" -> "Point",
"coordinates" -> Json.arr(lon, lat)
)
}
}
object Location {
implicit val reads: Reads[Location] = Json.reads[LonLat]
}
现在你可以做:
val locationJson = Json.parse("""{"lon": 48.858596, "lat": 2.294481}""")
locationJson.transform(of[LonLat].map(_.toPoint))
// Output:
// JsSuccess({"type":"Point","coordinates":[48.858596,2.294481]},)
现在您可以将其插入转换中,例如:
(__ \ 'location).json.update(of[LonLat].map(_.toPoint))
但是在此转换中,您将剩下 lat
和 lon
字段。所以删除它们:
(__ \ 'location).json.update(of[LonLat].map(_.toPoint)) andThen
(__ \ 'location \ 'lat).json.prune andThen
(__ \ 'location \ 'lon).json.prune
在我看来,不可能将其简化,因为 update
是同类中唯一的操作 - 恰好是 deep-merge.