如何在 Scala 中使用 Circe 将嵌套的 json 解码为 List[Object]

问题描述

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

done(AuthData authData){
  print(authData);

  /// You can pass the [AuthData] object to a 
  /// post-authentication screen. It contaions 
  /// all the user and OAuth data collected during
  /// the authentication process. In this example,/// our post-authentication screen is "complete-profile".
  Navigator.pushReplacementNamed(
      context,'/complete-profile',arguments: authData
  );
}

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

{
    "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)
    }
}

有关如何修复错误的任何说明将不胜感激。

解决方法

你在这里混合了一些东西。在您的 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 中运行。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...