我正在尝试使用Circe的自定义编解码器将json解码为特征列表Feature
,该特征列表分为两种情况:
trait Feature {
def name: String
def index: Int
def frequency: Int
}
case class NumericFeature(name, index, frequency) extends Feature
case class SetFeature(name, index, set, frequency) extends Feature
来自此处显示的json:
[
{
"name" : "ElectionReturns_G16CountyTurnoutAllRegisteredVoters",
"index" : 1770,
"frequency" : 2992
},
{
"name" : "CommercialDataLL_Home_Owner_Or_Renter",
"index" : 1112,
"set" : [
"Likely Homeowner",
"",
"Likely Renter",
],
"frequency" : 2537
},
.
.
.
.
]
这是适用于案例类又名单个实例的代码:
{
"name" : "ElectionReturns_G16CountyTurnoutAllRegisteredVoters",
"index" : 1770,
"frequency" : 2992
}
import io.circe.Json
import io.circe._
import io.circe.parser._
implicit val decoder: Decoder[Feature] = new Decoder[Feature] {
final def apply(h: HCursor): Decoder.Result[Feature] = for {
name <- h.get[String]("name")
index <- h.get[Int]("index")
set <- h.getOrElse[Set[String]]("set")(Set[String]())
frequency <- h.get[Int]("frequency")
feature: Feature = set match {
case s if s.isEmpty => new NumericFeature(name, index, frequency)
case _ => new SetFeature(name, index, set, frequency)
}
} yield feature
}
val decoded = decoder.decodeJson(parse(json).getOrElse(Json.Null))
如何调整它以输出列表?我曾尝试仅将解码器的输出类型更改为List[Feature]
,因为我认为for循环会生成一个列表,但事实并非如此。
这是我尝试在解码器中返回Decoder [List [Feature]]:
implicit val decoder: Decoder[List[Feature]] = new Decoder[List[Feature]] {
final def apply(h: HCursor): Decoder.Result[List[Feature]]= {
val feature = for {
name <- h.get[String]("name")
index <- h.get[Int]("index")
set <- h.getOrElse[Set[String]]("set")(Set[String]())
frequency <- h.get[Int]("frequency")
feature: Feature = set match {
case s if s.isEmpty => new NumericFeature(name, index, frequency)
case _ => new SetFeature(name, index, set, frequency)
}
} yield feature
feature.asInstanceOf[Decoder.Result[List[Feature]]]
}
}
val decoded = decoder.decodeJson(parse(json).getOrElse(Json.Null))
答案 0 :(得分:0)
只要您在范围内拥有io.circe.parser.decode
,就使用Decoder[Feature]
:
io.circe.parser.decode[Seq[Feature]](json)
您不必提供Decoder[Seq[Feature]]
。
答案 1 :(得分:-1)
尝试使用自定义解码器。这种方法对我有用:
import cats.Show
import cats.implicits._
import io.circe.Decoder
object Feature {
implicit val featureDecoder: Decoder[Feature] = List[Decoder[Feature]](
Decoder[NumericFeature].widen,
Decoder[SetFeature].widen
).reduceLeft(_ or _)
}