Json 从一个海岸到另一个海岸:最佳模式;“嵌套”;转变

Json 从一个海岸到另一个海岸:最佳模式;“嵌套”;转变,json,scala,playframework,playframework-2.0,Json,Scala,Playframework,Playframework 2.0,我越来越喜欢玩json海岸到海岸的模式,尤其是它使用的组合器。我有一些复杂的案子,我正在一起讨论。我知道有更好的方法,但我对combinator构建功能的方法还不熟悉 我想把这个转过来: { "somearray": [ { "field1": "value1", "field2": "value1", "key": "key1" }, { "field1": "second1", "field2": "second1",

我越来越喜欢玩json海岸到海岸的模式,尤其是它使用的组合器。我有一些复杂的案子,我正在一起讨论。我知道有更好的方法,但我对combinator构建功能的方法还不熟悉

我想把这个转过来:

{
 "somearray": [
   { 
     "field1": "value1",
     "field2": "value1",
     "key": "key1"
   },
   { 
     "field1": "second1",
     "field2": "second1",
     "key": "key2"
   }
  ]
 }
为此:

{
 "someObj": {
   "key1":
   { 
     "field1": "value1",
     "field2": "value1"
   },
   "key2":
   { 
     "field1": "second1",
     "field2": "second1"
   }
  ]
 }
我可以让它工作,但我退出了转换:

 (__ \ "someObj").json.copyFrom(__ \ "someArray".json.pick.map {
   case JsArray(arr) => {
     JsObject(arr.map(a =>
       a.transform(<A transform function to prune key>).map(pruned => {
         ((a \ "key").as[String], pruned)
       }).flatMap({
         case JsSuccess(result, _) => Seq(result)
         case other => Nil
       })
   }
   case other => JsNull
 })
(uu \“someObj”).json.copyFrom(uu \“someArray.json.pick.map{
案例JsArray(arr)=>{
JsObject(arr.map)(a=>
a、 transform().map(修剪=>{
((一个\“键”).as[String],删减)
}).平面图({
案例JsSuccess(结果)=>序号(结果)
其他情况=>无
})
}
case other=>JsNull
})
这段代码有一些问题:我知道它很冗长,我知道我假设“key”与字符串类型一起出现,我需要这个flatMap将我从JsResult中解救出来,并转换成一些可以用来构建JsObject的JsValue

看来我应该可以

1) 创建子转换,即
a.transform()
可以嵌套在父转换中,而无需解压缩和重新打包json对象

谢谢。

这怎么样(忽略这段代码仍然存在您已经提到的相同问题)

def elementTransform=for{

我建议看看Mandubian的JsZipper:这让我们的生活简单多了。
 def elementTransform = for {
    keyValue <- (__ \ 'key).json.pick  // picks value for key field
    obj <- (__ \ 'key).json.prune // returns object without the key field
    res <- (__ \ keyValue.as[String]).json.put(obj) // uses the keyValue as a field name
  } yield res

  val transform = (__ \ "someObj").json.copyFrom((__ \ "someArray").json.pick[JsArray].map(
    _.value.foldLeft[JsResult[JsObject]](JsSuccess(Json.obj()))(
      (obj, a) =>
        for {
          o <- obj
          field <- a.transform(elementTransform)
        } yield o ++ field
    ).fold(_ => JsNull, identity)
  ))