首页 > 解决方案 > 使用 circe 在 Scala 中修改 JSON 数组

问题描述

我有一个带有数组的 JSON 字符串,如下所示:

{
"cars": {
    "Nissan": [
        {"model":"Sentra", "doors":4},
        {"model":"Maxima", "doors":4}
    ],
    "Ford": [
        {"model":"Taurus", "doors":4},
        {"model":"Escort", "doors":2}
    ]
}
}

我想编辑一个新的卡片品牌,在 scala 使用circe
代替

"Nissan": [
        {"model":"Sentra", "doors":4},
        {"model":"Maxima", "doors":4},
    ]

我想有一个结果:

"Nissan": [
        {"model":"Sentra", "doors":1000},
    ],

谢谢。

标签: scalacirce

解决方案


说明书后做的,下次也照样做!

除了您的 JSON 无效(数组中对象的尾随逗号"Nissan"之外,它应该看起来像这样:

import cats.syntax.either._
import io.circe._, io.circe.parser._

val json: String = """
{
"cars": {
    "Nissan": [
        {"model":"Sentra", "doors":4},
        {"model":"Maxima", "doors":4}
    ],
    "Ford": [
        {"model":"Taurus", "doors":4},
        {"model":"Escort", "doors":2}
    ]
}
}
"""

val newJson = parse(json).toOption
  .flatMap { doc =>
    doc.hcursor
      .downField("cars")
      .downField("Nissan")
      .withFocus(_ =>
          Json.arr(
            Json.fromFields(
              Seq(
                ("model", Json.fromString("Sentra")),
                ("doors", Json.fromInt(1000))
              )
            )
          )
      )
      .top
  }

newJson match {
  case Some(v) => println(v.toString)
  case None => println("Failure!")
}

试试看!(重新运行以查看正确的缩进!)


newJson实际上是一个Option,所以如果解析或修改失败,你会得到None.

调用toOptionparse(json)返回的Either[Json](解析成功/失败)转换为Option[Json].

我们首先需要使用 an Option[Json],因为也.top返回 a Option[Json](修改成功/失败)。

这样我们就可以flatMap而且不必处理任何嵌套类型(见这里)。


推荐阅读