scala - 如何使用 Scala 中的 Play json 更新列表中的每个字段

标签 scala playframework play-json

我有以下 json 字符串:

{
   "id":123,
   "students":[
      {
         "collected":{
            "field":"field_1"
         },
         "attr":[{
            "name":"test_name",
            "age":"17",
            "color":"blue"
         }]
      }
   ]
}

我想更新我所有“学生”列表中“attr”对象中的所有元素。 通过更新,我的意思是我需要将值更新为键和值的连接字符串

{
   "id":123,
   "students":[
      {
         "collected":{
            "field":"field_1"
         },
         "attr":[{
            "name":"nametest_name",
            "age":"age17",
            "color":"colorblue"
         }]
      }
   ]
}

我遇到了 JsValue 的转换方法。这是我的变压器:

val jsonTransformer = (__ \ 'students).json.update(
  of[JsArray].map{
    case JsArray(list) =>
      list.map(o => o)
  }
)

我的变压器没有改变任何东西,因为我似乎找不到遍历“attr”字段的方法。

有人可以给我提供见解吗?

最佳答案

将以下内容作为输入(其中 attr 是对象数组):

   val input =
      """
        |{
        |   "id":123,
        |   "students":[
        |      {
        |         "collected":{
        |            "field":"field_1"
        |         },
        |         "attr":[{
        |            "name":"test_name",
        |            "age":"17",
        |            "color":"blue"
        |         }]
        |      },
        |      {
        |         "collected":{
        |            "field":"field_2"
        |         },
        |         "attr":[{
        |            "name":"test_name2",
        |            "age":"18",
        |            "color":"red"
        |         }]
        |      }
        |   ]
        |}
        |""".stripMargin

我们可以应用以下转换器来获得所需的结果:

    val attrTransformer = (__ \ "attr").json.update {
      __.read[JsArray].map {
        case JsArray(values) =>

          val updatedValues = values.map { x =>
            JsObject(x.as[JsObject].fields.map { z =>
              val (key, value) = z
              (key, JsString(key + value.as[String]))
            })
          }

          JsArray(updatedValues)
      }
    }

    val transformer = (__ \ "students").json.update(Reads.list(attrTransformer).map(x => JsArray(x)))

    val output = json.transform(transformer).get

转换后的输出将是:

{
  "students" : [ {
    "collected" : {
      "field" : "field_1"
    },
    "attr" : [ {
      "name" : "nametest_name",
      "age" : "age17",
      "color" : "colorblue"
    } ]
  }, {
    "collected" : {
      "field" : "field_2"
    },
    "attr" : [ {
      "name" : "nametest_name2",
      "age" : "age18",
      "color" : "colorred"
    } ]
  } ],
  "id" : 123
}

旧答案

考虑以下输入(其中 attr 不是 JsObject 数组):

    val input =
      """
        |{
        |   "id":123,
        |   "students":[
        |      {
        |         "collected":{
        |            "field":"field_1"
        |         },
        |         "attr":{
        |            "name":"test_name",
        |            "age":"17",
        |            "color":"blue"
        |         }
        |      },
        |      {
        |         "collected":{
        |            "field":"field_2"
        |         },
        |         "attr":{
        |            "name":"test_name2",
        |            "age":"18",
        |            "color":"red"
        |         }
        |      }
        |   ]
        |}
        |""".stripMargin

一个简单的解决方案是创建一个具有更新值的新 JsObject,如下所示。 (没有任何验证)

    val students = (Json.parse(input) \ "students").as[JsArray]
    val requiredStudents = students.value.map { student =>
      val attr = student \ "attr"

      val updatedAttributes = attr.get.as[JsObject].fields.map { x =>
        val (key, value) = x
        (key, JsString(key + value.as[String]))
      }

      val requiredStudent = student.as[JsObject] ++ Json.obj("attr" -> JsObject(updatedAttributes))
      requiredStudent
    }

    requiredStudents.foreach(println)

每个学生的输出如下:

{"collected":{"field":"field_1"},"attr":{"name":"nametest_name","age":"age17","color":"colorblue"}}
{"collected":{"field":"field_2"},"attr":{"name":"nametest_name2","age":"age18","color":"colorred"}}

关于scala - 如何使用 Scala 中的 Play json 更新列表中的每个字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60463947/

相关文章:

java - 如何以正确的方式创建 Scala 项目?

scala - 将元组与null匹配

authentication - Play Framework 句柄授权而不是身份验证

java - 如何通过 Uploadify 将 session cookie 传递给 Play?

scala - 将验证约束与解码分离

json - 将 List[JsResult[A]] 排序为 JsResult[List[A]]

scala - Slick update 返回更新后的对象

scala - scalaz中的商店是什么

java - Play Framework 中的发布请求中的表单值为null

json - Map[Locale, String] 的 Scala Play Json 格式