首页 > 解决方案 > Scala 操作 json 对象

问题描述

我有一个以某种格式生成的动态 json 对象,我想操纵该对象以将其映射到 scala 中的另一种格式。问题是字段的名称是动态的,因此“field1”和“field2”可以是任何名称。有没有办法在scala中动态地做到这一点?

原始对象:

{
 "field1": {
  "value" "some value 1",
  "description": "some test description",
  ... 
 },
 "field2": {
  "value" "some value 2",
  "description": "some test description",
  ... 
 }
}

我想把它转换成类似的东西:

{
 "field1": "some value 1",
 "field2": "some value 2"
}

标签: jsonscalaazure-data-flow

解决方案


您可以收集所有keys然后检查是否downField("value")存在

import io.circe._
import io.circe.literal.JsonStringContext

object CirceFieldsToMap {

  def main(args: Array[String]): Unit = {
    val json: Json =
      json"""{
             "field1": {
                "foo" : "bar1",
                "value" : "foobar1"
             },
             "field2": {
                "foo" : "bar2",
                "value" : "foobar2"
             },
             "field3": {
                "foo" : "bar2"
             }
             }"""

    implicit val decodeFoo = new Decoder[Map[String, Option[String]]] {
      final def apply(c: HCursor): Decoder.Result[Map[String, Option[String]]] = {
        val result = c.keys.get //// You should handle the .get properly ( if None it breaks)
                            .toList
                            .foldLeft(List.empty[(String, Option[String])]) { case (acc, key) =>
          acc :+ (key, c.downField(key).downField("value").as[String].toOption)
        }
        Right(result.toMap)
      }
    }

    val myField01 = json.as[Map[String, Option[String]]]
    println(myField01)   //Right(Map(field1 -> Some(foobar1), field2 -> Some(foobar2), field3 -> None))


  }

}

推荐阅读