【问题标题】:Convert JSON object to List<>将 JSON 对象转换为 List<>
【发布时间】:2021-03-28 19:46:16
【问题描述】:

我想将 JSON 对象转换成不同的格式。我的 JSON 对象看起来像。

{
    "schema": [
        {
            "name": "cust_id",
            "data_type": "String",
            "nullable": true
        },
        {
            "name": "source_type",
            "data_type": "String",
            "nullable": true
        }
    ]
}

我想要以下输出:

val colType = List(("cust_id","String",true),("source_type","String",true))

我想要在 Scala 中进行转换。

【问题讨论】:

  • 您自己将 json 解析到该列表时遇到什么问题?
  • 我是 scala 的新手。这就是为什么我没有理解逻辑。
  • 提供的答案提供创建一个类,而您在问题中要求一个元组。你指的是哪一个?

标签: arrays json scala


【解决方案1】:

你也可以使用 spray.json。

在 build.sbt 中添加依赖

libraryDependencies += "io.spray" %% "spray-json" % "1.3.6"

应用:

import spray.json._

//create your model classes
case class MyItem(name: String, data_type: String, nullable: Boolean)
case class MySchema(schema: Seq[MyItem])

//prepare JSON protocol
trait MyJsonProtocol extends DefaultJsonProtocol {
  //MyItem has 3 fields, so you have to use jsonFormat3
  implicit val myItemFormat: RootJsonFormat[MyItem] = jsonFormat3(MyItem)

  //MySchema has 1 field, so you have to use jsonFormat1
  implicit val mySchemaFormat: RootJsonFormat[MySchema] = jsonFormat1(MySchema)
}

//extends your application with your JSON protocol
object MyApplication extends App with MyJsonProtocol {
  val json =
    """{
      |"schema": [{
      |        "name": "cust_id",
      |        "data_type": "String",
      |        "nullable": true
      |    },
      |    {
      |        "name": "source_type",
      |        "data_type": "String",
      |        "nullable": true
      |    }
      |]
      |}""".stripMargin
  
  //execute parsing
  val parsed = json.parseJson.convertTo[MySchema]

  //true
  println(parsed.schema == List(MyItem("cust_id","String",true), MyItem("source_type","String",true)))
}

【讨论】:

    【解决方案2】:

    Circe怎么样?

    import io.circe._, io.circe.generic.auto._, io.circe.parser._, io.circe.syntax._
    import cats.syntax.show._
    
    case class Schema(schema: List[Container])
    case class Container(name:String, data_type: String, nullable: Boolean)
    
    val json = """
    {
    "schema": [{
            "name": "cust_id",
            "data_type": "String",
            "nullable": true
        },
        {
            "name": "source_type",
            "data_type": "String",
            "nullable": true
        }
    ]
    }"""
    
    decode[Schema](json) match {
      case Right(result) => println(result.schema.map{case Container(a,b,c) => (a,b,c)})
      case Left(failure) => println(failure.show)
        
    }
    

    【讨论】:

    • 感谢@rysh 提供解决方案。如果我们从本地目录读取 json 文件,那么解析仍然是一样的吗?
    • Circe 没有读取文件的 API,因此您可以使用 Scala 标准库中的 Source.fromFile 或类似的东西。
    • circe 确实有读取文件的 API,请查看JawnParser
    • 添加类似val jsonString = scala.io.Source.fromFile("file.json").mkString
    【解决方案3】:

    我将演示如何使用play-json 来实现。如果您想将其序列化为案例类,如其他答案中所示,您可以定义类及其序列化程序:

    case class Schema(name: String, data_type: String, nullable: Boolean)
    
    object Schema {
      implicit val format: OFormat[Schema] = Json.format[Schema]
    }
    
    case class Schemas(schema: Seq[Schema])
    
    object Schemas {
      implicit val format: OFormat[Schemas] = Json.format[Schemas]
    }
    

    然后只需调用:

    println(Json.parse(jsonString).as[Schemas])
    

    代码在Scastie 运行。

    但如果你真的想要元组列表,你可以这样做:

    val path = JsPath \ "schema"
    
    val schemas = path(Json.parse(jsonString)) match {
      case List(arr) =>
        arr match {
          case arr: JsArray =>
            arr.value.map(_.validate[JsObject] match {
              case JsSuccess(value, _) =>
                value.values.toList match {
                  case List(a, b, c) =>
                    (a, b, c)
                  case _ => ???
                }
              case JsError(errors) =>
                ??? // Error handling
            }).toList
          case _ => ??? // Error handling
        }
      case _ => ??? // Error handling
    }
    

    代码在Scastie运行

    【讨论】:

      猜你喜欢
      • 2017-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多