简体   繁体   English

模式与Scala中的列表匹配

[英]Pattern matching a List in scala

So I am trying to pattern match a List of a custom object which has been converted from Json . 所以我试图模式匹配自Json转换的自定义对象的List The compiler cannot determine the content of Sequences , eg List[Int] is the same as List[String] so I'm currently not able to differentiate between the different objects and therefore cannot handle them correctly. 编译器无法确定Sequences的内容,例如List[Int]List[String]相同,因此我目前无法区分不同的对象,因此无法正确处理它们。

I have retrieved Json data, transformed it and then successfully mapped it to my models so the myFunction (below) is the part which is causing the problem - in not being able to identify the data type: 我已经检索了Json数据,对其进行了transformed ,然后成功transformed其映射到我的模型中,因此myFunction (以下)是导致问题的部分-无法识别数据类型:

  trait SuperT

  case class User(firstname: String, firstname: String, dob: Option[Date]) extends SuperT

  case class Country(name: String, continent: Option[String], hemisphere: Option[String]) extends SuperT

  def myFunction(jsRes: JsResult[Seq[SuperT]])(implicit request: Request[AnyContent]) = {

    jsRes match {
      case JsSuccess(data: List[SuperT], path: JsPath) => data match {
        // cannot find the differences between the following 2 case types
        case u: List[User] => Ok(views.html.db.user.index(Some(u))
        case c: List[RgnM] => Ok(views.html.db.country.index(Some(c))
      }
      case e: JsError => Ok(JsError.toJson(e))
    }

  }

Any help or insight is appreciated! 任何帮助或见解表示赞赏!

it's similar but not the same and importantly the solution for that question doesn't seem helpful 相似但不相同,重要的是该问题的解决方案似乎无济于事

The problem is exactly the same as in the question @markusthoemmes linked. 问题完全一样的链接的问题@markusthoemmes。 However, it may not be obvious which solutions are applicable and how they need to be adapted, especially without enough Scala experience. 但是,可能不清楚哪种解决方案适用,以及如何调整它们,尤其是在没有足够的Scala经验的情况下。

If you just have a List[SuperT] obtained from somewhere, Manifest / ClassTag / TypeTag based solutions won't help. 如果您只是从某个地方获得List[SuperT]TypeTag基于Manifest /类ClassTag /类型TypeTag的解决方案将无济于事。 They require having a List[User] at some stage. 他们需要在某个阶段拥有一个List[User]

case JsSuccess(data: List[SuperT], path: JsPath) => data match {
  case first :: _ =>
    first match {
      case _: User => 
        Ok(views.html.db.user.index(Some(data.asInstanceOf[List[User]]))
      case _: Country =>
        Ok(views.html.db.country.index(Some(data.asInstanceOf[List[Country]]))
    }
  case _ => // what do you want to do if the list is empty (or null)?
}

should work if you can assume the list contains either only User s or only Country es. 如果您可以假设列表仅包含UserCountry则应该可以User Otherwise you can use partition or groupBy to split into lists by class and decide what to do with each. 否则,您可以使用partitiongroupBy按类拆分为列表,然后决定对每个列表进行处理。

But you should also consider why you have a List[SuperT] in the first place; 但是,您还应该考虑为什么首先要有一个List[SuperT] at the moment you create it, don't you have information about whether users or countries will be contained in the response? 在您创建它的那一刻,您是否没有有关响应中是否包含用户或国家的信息? If you do, it can be passed together with the list and solve your problem without type-matching ugliness. 如果这样做,可以将其与列表一起传递并解决您的问题,而不必进行类型匹配的丑陋处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM