首页 文章

通用 Map 上的Scala模式匹配

提问于
浏览
1

什么是在Scala中进行模式匹配时处理泛型和擦除的最佳方法(在我的案例中为Map) . 我正在寻找一个没有编译器警告的正确实现 . 我有一个函数,我想从中返回Map [Int,Seq [String]] . 目前代码如下:

def teams: Map[Int, Seq[String]] = {
    val dateam = new scala.collection.mutable.HashMap[Int, Seq[String]]

    // data.attributes is Map[String, Object] returned from JSON parsing (jackson-module-scala)
    val teamz = data.attributes.get("team_players")
    if (teamz.isDefined) {
      val x = teamz.get
      try {
        x match {
          case m: mutable.Map[_, _] => {
            m.foreach( kv => {
              kv._1 match {
                case teamId: String => {
                  kv._2 match {
                    case team: Seq[_] => {
                      val tid: Int = teamId.toInt
                      dateam.put(tid, team.map(s => s.toString))
                    }
                  }
                }
              }
            })
          }
        }
      } catch {
        case e: Exception => {
          logger.error("Unable to convert the team_players (%s) attribute.".format(x), e)
        }
      }

      dateam
    } else {
      logger.warn("Missing team_players attribute in: %s".format(data.attributes))
    }
    dateam.toMap
}

2 回答

  • 1

    使用 for comprehension(有一些内置的模式匹配)是合理的 . 我们还可以考虑 Map 是一个元组列表,在我们的 (String, Object) 类型的情况下 . 同样,我们将忽略此示例可能的异常,因此:

    import scala.collection.mutable.HashMap
    
    def convert(json: Map[String, Object]): HashMap[Int, Seq[String]] = {
    
      val converted = for {
        (id: String, description: Seq[Any]) <- json
      } yield (id.toInt, description.map(_.toString))
    
      HashMap[Int, Seq[String]](converted.toSeq: _*)
    }
    

    所以,我们的 for 理解只考虑了 (String, Seq[Any]) 类型的元组,然后将 String 转换为 IntSeq[Any]Seq[String] . 并使 Map 变得可变 .

  • 2

    使用Scala库来处理它 . 有一些基于 Jackson (Play的ScalaJson,例如 - 参见this article单独使用它),以及不基于 Jackson 的图书馆(我的首选是Argonaut,尽管你也可以使用Spray-Json) .

    这些库和其他库解决了这个问题 . 手工操作很尴尬,容易出错,所以不要这样做 .

相关问题