【问题标题】:Parsing recursive JSON structure with Lists in Scala在 Scala 中使用列表解析递归 JSON 结构
【发布时间】:2022-01-07 09:48:11
【问题描述】:

我有以下 JSON 结构,但我找不到在 Scala 中解析它的好方法(我正在使用 circe BTW)

{
  "name": "xx",
  "args": [
    {"name":"xy", "args": []},
    [
      {"name":"xy", "args": []},
      {"name":"xy", "args": [[]]}
    ],
    [
      [
        {"name":"xy", "args": [{"name":"xy", "args": []}]}
      ]
    ]
  ]
}

基本上,它是一个递归结构,可以包含对象、对象列表、列表列表、列表列表...或对象和列表。

我该如何处理?我正在考虑一些递归类型,但我不确定。

【问题讨论】:

  • 这是一个有效的 JSON 吗?
  • @GaëlJ 是的。 - 嗯,它在13 行有一个尾随逗号,但除此之外是有效的

标签: json scala circe


【解决方案1】:

您需要将其建模为 ADT 并派生一个自定义 Decoder,如下所示:

import io.circe.{Decoder, DecodingFailure, parser}
import io.circe.generic.semiauto.deriveDecoder

sealed trait Arg
object Arg {
  final case class OneArg(name: String, args: List[Arg]) extends Arg
  final case class MultipleArgs(args: List[Arg]) extends Arg
  
  private implicit final val OneArgDecoder: Decoder[OneArg] = deriveDecoder
  
  implicit final val ArgDecoer: Decoder[Arg] =
    Decoder.instance[Arg] { cursor =>
      cursor.focus match {
        case Some(json) =>
          // Here you may also ask if it is an array before to attempt to get it as a List[arg], and if not then provide a custom failure.
          if (json.isObject) json.as[OneArg]
          else json.as[List[Arg]].map(MultipleArgs)
        
        case None =>
          Left(DecodingFailure("Empty cursor", cursor.history))
      }
    }
}

可用于解码您的 JSON:https://scastie.scala-lang.org/BalmungSan/W0lLBYRzTIS3PC4E5i0wXA/26

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-05
    • 1970-01-01
    • 2018-12-31
    • 2019-05-30
    • 1970-01-01
    • 1970-01-01
    • 2014-04-02
    相关资源
    最近更新 更多