[英]How to correctly do Pattern matching by type in this case?
I have a use-case where I'd like to serialize a Saddle Frame to a Scala-Play Json. 我有一个用例,其中我想将鞍形框架序列化为Scala-Play Json。 I had it working for simple element types eg Double ie
Frame[DateTime, String, Double]
but now it becomes a bit more hairy trying to serialize Frame types whose elements are complex types eg Seq[(DateTime, Double)]
我让它适用于简单的元素类型,例如Double,即
Frame[DateTime, String, Double]
但是现在尝试序列化元素为复杂类型的Frame类型变得有些Seq[(DateTime, Double)]
例如Seq[(DateTime, Double)]
So I have the basic frameWrites implementation that works for primitive element types: 因此,我有适用于基本元素类型的基本frameWrites实现:
import play.api.libs.json._
import org.saddle._
import org.joda.time._
object JsonUtils {
implicit def frameWrites[RX, CX, E] = new Writes[Frame[RX, CX, E]] {
override def writes(frame: Frame[RX, CX, E]): JsValue = {
val json: JsArray = Json.arr(
(0 until frame.numRows).map { i =>
Json.obj(
frame.rowIx.at(i).toString ->
(0 until frame.numCols).map { j =>
Json.obj(
frame.colIx.at(j).toString -> cellWrites(frame.at(i, j))
)
}
)
})
json
}
}}
So I created a cellWrites
to be able to handle complex element types like so: 因此,我创建了一个
cellWrites
来处理复杂的元素类型,如下所示:
object JsonUtils {
implicit def cellWrites[E](elem: E)(implicit tag: ClassTag[E]): JsValue = {
elem match {
case seq: Seq[(DateTime, Double)] => {
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this should but doesn't happen
Json.arr(
seq.map { case (dt: DateTime, value: Double) =>
Json.obj(dt.toString -> JsNumber(value))
}
)
}
case doubleValue: Double => JsNumber(doubleValue)
case _ => JsString(elem.toString)
}
}}
The problem is that my Frame or type Frame[String, String, Seq[(DateTime, Double)]]
is never matching the appropriate first case in cellWrites
. 问题是我的Frame或
Frame[String, String, Seq[(DateTime, Double)]]
类型从不匹配cellWrites
合适的第一种情况。 I also tried using the implicit tag type information but could not find the way to use it for Pattern matching. 我也尝试使用隐式标签类型信息,但是找不到将其用于模式匹配的方法。 This is a test-case sample Frame I use:
这是我使用的测试用例示例框架:
val today = DateTime.parse("2017-11-14T13:00:00.000+01:00")
val colIx = Index("x", "y")
val data = Seq(
Series(
"a" -> Seq(
today.minusHours(2) -> 2.0,
today.minusHours(1) -> 1.0,
today.minusHours(0) -> 0.0
),
"b" -> Seq(
today.minusHours(1) -> 1.0,
today.minusHours(0) -> 0.0
)
),
Series(
"a" -> Seq(
today.minusHours(5) -> 5.0,
today.minusHours(4) -> 4.0,
today.minusHours(3) -> 3.0
),
"b" -> Seq(
today.minusHours(4) -> 4.0,
today.minusHours(3) -> 3.0
)
)
)
val frame: Frame[String, String, Seq[(DateTime, Double)]] = Frame(data, colIx)
println(frame)
Note that all the code above compiles fine. 请注意,以上所有代码都可以正常编译。 However, the Pattern matching by cell element type is not working.
但是,按单元格元素类型进行的模式匹配不起作用。
OK found it, elem
was actually of type org.saddle.scalar.Scalar[E]
therefore this works: OK找到了,
elem
实际上是org.saddle.scalar.Scalar[E]
类型的,因此可以这样工作:
implicit def cellWrites[E](scalar: Scalar[E]): JsValue = {
val elem = scalar.get
elem match {
case seq: Seq[(DateTime, Double)] => {
Json.arr(
seq.map { case (dt: DateTime, value: Double) =>
Json.obj(dt.toString -> JsNumber(value))
}
)
}
case doubleValue: Double => JsNumber(doubleValue)
case _ => JsString(elem.toString)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.