我有以下 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/