如何递归解析和转换json对象

时间:2019-04-16 18:12:03

标签: scala playframework

在Scala Play 2.7中递归转换Json值的最佳方法是什么。

我有类似的东西:

val json: JsValue = Json.parse("""
  {
    "name" : "Watership Down",
    "trips" : 1653538901909,
    "location" : {
      "lat" : 51.235685,
      "long" : -1.309197
    },
    "residents" : [ {
      "name" : "Fiver",
      "age" : 4,
      "role" : null
    }, {
      "name" : "Bigwig",
      "age" : 6,
      "role" : "Owsla"
    } ]
  }
  """.stripMargin)

val FutJsValue = Future.successful(json)

val futMapJsVal : Future[Map[String, JsValue]] = FutJsValue.map(_.as[JsObject].value)

我想为所有后代转换每个futMapJsVal的地图编号值。例如,如果“地图”值大于10,则将其加1并返回。它忽略所有其他值类型。

我从这样的事情开始:

  private def parseObject(jsObj : JsObject) : Future[JsValue] = {
    val result = jsObj.value.map { case (key, jsValue) =>
      jsValue match {
        case n: JsNumber if n.as[Long] > 10L  => (key, addTen(n.as[Long]))
        case o: JsObject                      => (key, parseObject(o))
        case _                                => (key, Future.successful(jsValue))
      }
    }

    Future.traverse(result) { case (k, fv) => fv.map(k -> _) }.map(_.toMap).map(i => Json.toJson(i))
  }

  def addTen(number: Long) : Future[JsValue]

  futMapJsVal.flatMap(parseObject)

我决定采用一种明确的递归方法。但是,我不太喜欢这种解决方案,并且由于某种原因,它的运行也不正常。

有什么更聪明的解决方案?

注意:以上json有效负载的结构未压缩,json可以具有任何结构。

我希望json对象最终看起来像这样:

{
    "name" : "Watership Down",
    "trips" : 1653538901910,
    "location" : {
      "lat" : 52.235685,
      "long" : -1.309197
    },
    "residents" : [ {
      "name" : "Fiver",
      "age" : 4,
      "role" : null
    }, {
      "name" : "Bigwig",
      "age" : 6,
      "role" : "Owsla"
    } ]
  }

0 个答案:

没有答案