在 Scala 中将 Json 对象解析为大小写 类?
Parse Json Objects into case classes in Scala?
我有一个 Json 对象数组。所有这些对象都遵循以下两种结构之一:
第一个是这样的:
{
"uuid": "321,
"uuidType": "series",
"title": "a movie",
"segments": [
"movie"
],
"seriesIds": [
"123"
]
}
第二个像这样:
{
"uuid": "1234",
"uuidType": "programme",
"title": "programme title",
"type": "movie",
"segments": [
"movies"
],
"programmeIds": [
"321"
]
}
但是,我想将这些对象解析为相同的大小写 class,如下所示:
case class SearchResult(uuid: String, uuidType: String, title: String, segments: List[String], ids: List[String])
因此对于第二种类型的对象,类型键和值将被忽略,第一个对象的 seriesId 和第二个对象的 programmeId 将进入案例的 ids 部分 class。但是我不知道该怎么做!我正在使用 Circe decode/encode json。
您可以在 circe 内编写自定义代码以获得您想要的效果,但在我看来,使用 circe 自动反序列化并将您的案例 class 定义为
会更简单
case class SearchResult(uuid: String, uuidType: String, title: String, segments: List[String], programmeIds: Option[List[String]], seriesIds: Option[List[String]])
并使用简单的 Scala 代码将其转换为 ID
您可以在 SearchResult 对象伴随中放置自定义解码器
斯卡拉 2.12
大约 0.9.3
import io.circe._
import io.circe.parser._
object Main extends App {
val jsonA =
"""{
"uuid": "321",
"uuidType": "series",
"title": "a movie",
"segments": [
"movie"
],
"seriesIds": [
"123"
]
}"""
val jsonB =
"""{
"uuid": "1234",
"uuidType": "programme",
"title": "programme title",
"type": "movie",
"segments": [
"movies"
],
"programmeIds": [
"321"
]
}"""
case class SearchResult(uuid: String, uuidType: String, title: String, segments: List[String], ids: List[String])
object SearchResult {
implicit val decoder: Decoder[SearchResult] = Decoder.instance { h =>
for {
uuid <- h.get[String]("uuid")
uuidType <- h.get[String]("uuidType")
title <- h.get[String]("title")
segments <- h.get[List[String]]("segments")
ids <- {
h.getOrElse[List[String]]("seriesIds")(h.get[List[String]]("programmeIds").getOrElse(Nil))
}
} yield SearchResult(uuid, uuidType, title, segments, ids)
}
}
val obj1 = decode[SearchResult](jsonA)
println(obj1)
val obj2 = decode[SearchResult](jsonB)
println(obj2)
}
我有一个 Json 对象数组。所有这些对象都遵循以下两种结构之一: 第一个是这样的:
{
"uuid": "321,
"uuidType": "series",
"title": "a movie",
"segments": [
"movie"
],
"seriesIds": [
"123"
]
}
第二个像这样:
{
"uuid": "1234",
"uuidType": "programme",
"title": "programme title",
"type": "movie",
"segments": [
"movies"
],
"programmeIds": [
"321"
]
}
但是,我想将这些对象解析为相同的大小写 class,如下所示:
case class SearchResult(uuid: String, uuidType: String, title: String, segments: List[String], ids: List[String])
因此对于第二种类型的对象,类型键和值将被忽略,第一个对象的 seriesId 和第二个对象的 programmeId 将进入案例的 ids 部分 class。但是我不知道该怎么做!我正在使用 Circe decode/encode json。
您可以在 circe 内编写自定义代码以获得您想要的效果,但在我看来,使用 circe 自动反序列化并将您的案例 class 定义为
会更简单case class SearchResult(uuid: String, uuidType: String, title: String, segments: List[String], programmeIds: Option[List[String]], seriesIds: Option[List[String]])
并使用简单的 Scala 代码将其转换为 ID
您可以在 SearchResult 对象伴随中放置自定义解码器
斯卡拉 2.12
大约 0.9.3
import io.circe._
import io.circe.parser._
object Main extends App {
val jsonA =
"""{
"uuid": "321",
"uuidType": "series",
"title": "a movie",
"segments": [
"movie"
],
"seriesIds": [
"123"
]
}"""
val jsonB =
"""{
"uuid": "1234",
"uuidType": "programme",
"title": "programme title",
"type": "movie",
"segments": [
"movies"
],
"programmeIds": [
"321"
]
}"""
case class SearchResult(uuid: String, uuidType: String, title: String, segments: List[String], ids: List[String])
object SearchResult {
implicit val decoder: Decoder[SearchResult] = Decoder.instance { h =>
for {
uuid <- h.get[String]("uuid")
uuidType <- h.get[String]("uuidType")
title <- h.get[String]("title")
segments <- h.get[List[String]]("segments")
ids <- {
h.getOrElse[List[String]]("seriesIds")(h.get[List[String]]("programmeIds").getOrElse(Nil))
}
} yield SearchResult(uuid, uuidType, title, segments, ids)
}
}
val obj1 = decode[SearchResult](jsonA)
println(obj1)
val obj2 = decode[SearchResult](jsonB)
println(obj2)
}