假设有以下json有效负载
val json = """{ "choices" : [ { "name" : "A" },{ "name" : "B" },{ "name" : "C" },{ "name" : "D" } ],"domain" : "Quizz","level" : "Test","mandatory": true }"""
我该如何将其转换为
val json = """{ "value":"B",}"""
从可用选择中随机选择“B”?
这是我到目前为止所得到的:
val cursor = parse(json).getOrElse(Json.Null).cursor for{ noMandatory<- cursor.downField("mandatory").flatMap(_.delete).map(_.top) withEmptyValue = noMandatory.deepMerge(Json.obj("value"->Json.Null)) }yield withEmptyValue
这会丢弃未使用的“强制”字段并插入一个空的“值”字段.从数组中获取一个随机值并将其置于“值”中会让我感到惊讶.
– 编辑
我尝试过使用hcursor,这使得上面更清楚(无论如何)
val cursor = parse(json).getOrElse(Json.Null).hcursor val noMandatory = cursor.downField("mandatory").delete val withEmptyValue = noMandatory.withFocus(_.deepMerge(Json.obj("value"->Json.Null)))
(我在上面的例子中使用的是0.5.1)
解决方法
不要将副作用与纯代码混合使用.所以我没有解决你的随机问题.
其次,我建议不要删除“选择”字段以保持简单.如果你愿意,可以在以后删除该字段.
第三,为了简单起见,将获取和转换阶段分开.在这里,您可以使用案例类来完成大部分工作.
我敢肯定这可能不是惯用的Circe解决方案,但它很好Scala:
import io.circe._,io.circe.generic.auto._,io.circe.parser._,io.circe.Syntax._ object ChooserApp extends App { val input = """{ "choices" : [ { "name" : "A" },"mandatory": true }""" val expected = """{ "choices" : [ { "name" : "A" },{ "name" : "B" },{ "name" : "C" },{ "name" : "D" } ],"value":"B","mandatory": true }""" case class ForJson(j: Json) { def choices: List[String] = { j.asObject .toList .flatMap(_ ("choices")) .flatMap(_.asArray) .flatten .flatMap(_.asObject) .flatMap(_ ("name")) .flatMap(_.asString) } def chosen(a: String): Json = { j.asObject .map(_.add("value",Json.fromString(a))) .map(Json.fromJsonObject) .getOrElse(j) } } val expectedList = List("A","B","C","D") val gotList = ForJson(parse(input).toOption.get).choices assert(gotList == expectedList,s"Expected $expectedList,got $gotList") val expectedJson = parse(expected).toOption.get val gotJson = ForJson(parse(input).toOption.get).chosen("B") assert(gotJson == expectedJson,s"Expected $expectedJson,got $gotJson") }