简体   繁体   English

在这种情况下,如何按类型正确进行模式匹配?

[英]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.

相关问题 关联类型的实例上的模式匹配困难 - Difficulty with pattern matching on an instance of an associated type 如何递归搜索 JSON 文件以查找与给定模式匹配的所有节点,并将 JSON 的“路径”返回到节点及其值? - How do I recursively search a JSON file for all nodes matching a given pattern and return the JSON 'path' to the node and it's value? 在对象上进行模式匹配时可以克服Scala中的类型擦除,这些对象可能是不同的Set或任何类型的Object - Overcoming type erasure in Scala when pattern matching on Objects which may be different Sets or any type of Object 模式匹配中的Scala擦除 - Scala erasure in pattern matching 如何在 json 模式模式中指定匹配文字星号 - How to specify matching a literal asterisk in a json schema pattern 模式与Scala中的列表匹配 - Pattern matching a List in scala Lisp Macro-如何正确输入类型 - Lisp Macro - how enter a type correctly 案例 Class 到 Json:关于如何在不使用外部 Json 库的情况下避免重复模式匹配的设计模式 - Case Class to Json: Design Pattern on How to Avoid Repetitive Pattern Match without Using External Json Lib JSON Jquery不区分大小写的匹配 - JSON Jquery Case Insensitive Matching 匹配模式后提取子字符串 - Extract substring after matching pattern
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM