【问题标题】:How to decode a nested json into a List[Object] using Circe in Scala如何在 Scala 中使用 Circe 将嵌套的 json 解码为 List[Object]
【发布时间】:2025-12-29 05:30:11
【问题描述】:

我有一个看起来像这样的 json:

{
    "results": {
        "result_1": {
            "text": "abc"
        },
        "result_2": {
            "text": "def"
        }
    }
}

我希望将其解码为如下所示的案例类:

case class Results(results: List[SingleResult])

case class SingleResult(text: String)

我希望为此编写一个解码器,但我当前的解码器没有编译。它看起来像这样:

implicit val singleResultDecoder: Decoder[SingleResult] = deriveDecoder[SingleResult]
implicit val ResultsDecoder: Decoder[Results] = new Decoder[Results] {
    override def apply(c: HCursor): Result[Results] = {
        for {
            results <- c.keys.map(_.map(k => c.downField(k).as[SingleResult]).toList)
        } yield Results(results = results)
    }
}

编译错误是:

Type mismatch : 
Required: scala.List[SingleResult]
Found: scala.List[Result[SingleResult]]

任何关于如何修复错误的指导都将不胜感激。

【问题讨论】:

    标签: json scala circe


    【解决方案1】:

    你在这里混合了一些东西。在您的 json 中,您没有列表,因为您正在尝试阅读它。你有一张地图。因此我们需要相应地拥有我们的Decoder

    implicit val ResultsDecoder: Decoder[Results] = new Decoder[Results] {
      override def apply(c: HCursor): Result[Results] = {
        for {
          results <- c.downField("results").as[Map[String, SingleResult]]
        } yield Results(results = results.values.toList)
      }
    }
    

    然后调用:

    val decodedFoo = circe.jawn.decode[Results](jsonString)
    println(decodedFoo)
    

    结果:

    Right(Results(List(SingleResult(abc), SingleResult(def))))
    

    代码在Scastie 中运行。

    【讨论】: