带圆光学的递归遍历JSON

时间:2019-03-26 12:12:38

标签: scala circe

我有json,结构复杂。像这样:

{
  "a":"aa",
  "b":"bb",
  "c":[
    "aaa",
    "bbb"
  ],
  "d":{
    "e":"ee",
    "f":"ff"
  }
}

我想将所有字符串值大写。 Documentation说:

root.each.string.modify(_.toUpperCase)

但是,只有根值像预期的那样大写。

如何使circe-optics递归遍历所有字符串值?
JSON结构事先未知。

这是Scastie上的expample


通过评论: 我期望所有字符串值都大写,而不仅仅是根值:

{
  "a":"AA",
  "b":"BB",
  "c":[
    "AAA",
    "BBB"
  ],
  "d":{
    "e":"EE",
    "f":"FF"
  }
}

2 个答案:

答案 0 :(得分:0)

这里是部分解决方案,例如,它不是完全递归的,但是它将使用您示例中的json解决问题:


val level1UpperCase = root.each.string.modify(s => s.toUpperCase)

val level2UpperCase = root.each.each.string.modify(s => s.toUpperCase)
val uppered = (level1UpperCase andThen level2UpperCase)(json.right.get)

答案 1 :(得分:0)

以下可能是执行此操作的新方法。为了完整起见,在此处添加它。

  import io.circe.Json
  import io.circe.parser.parse
  import io.circe.optics.JsonOptics._
  import monocle.function.Plated

  val json = parse(
    """
      |{
      |  "a":"aa",
      |  "b":"bb",
      |  "c":[
      |    "aaa",
      |    {"k": "asdads"}
      |  ],
      |  "d":{
      |    "e":"ee",
      |    "f":"ff"
      |  }
      |}
      |""".stripMargin).right.get
  val transformed = Plated.transform[Json] { j =>
    j.asString match {
      case Some(s) => Json.fromString(s.toUpperCase)
      case None    => j
    }
  }(json)

  println(transformed.spaces2)

给予

{
  "a" : "AA",
  "b" : "BB",
  "c" : [
    "AAA",
    {
      "k" : "ASDADS"
    }
  ],
  "d" : {
    "e" : "EE",
    "f" : "FF"
  }
}