Cant模式匹配Scala中的Map [String,Any]

时间:2018-04-12 22:28:12

标签: json scala pattern-matching

我试图将这个Map字符串化为json字符串:

val value = Map(
        "items" -> Seq(
            Map(
                "type" -> Seq("http://data-vocabulary.org/Product"),
                "properties" -> Map(
                    "brand" -> Seq("Bridgestone"),
                    "category" -> Seq("Truck Tires"),
                    "name" -> Seq("R-195F"),
                    "photo" -> Seq(""),
                    "price" -> Seq("$300.09"),
                    "url" -> Seq("http://www.bridgestonetrucktires.com")
                )
            )
        )
    )

用这种方法:

    def beautify(map: Map[String, Any]): String = {
    val keys = map.keys.toSeq
    keys.map(key => {
        val value: Any = map.get(key).get
        value match {
            case x: Map[String, Any] => "\"" + key + "\": " + beautify(x)
            case x: Seq[String] => "\"" + key + "\": " + x.mkString("[", ", ", "]")
            case x: Seq[Map[String, Any]] => x.map(el => beautify(el)).mkString("[", ", ", "]")
        }
    }).mkString("{", ", ", "}")
}

问题在于,当我获得密钥“items”时,并尝试匹配此处的值:

value match {
            case x: Map[String, Any] => "\"" + key + "\": " + beautify(x)
            case x: Seq[String] => "\"" + key + "\": " + x.mkString("[", ", ", "]")
            case x: Seq[Map[String, Any]] => x.map(el => beautify(el)).mkString("[", ", ", "]")
        }

它与这一行匹配:

case x: Seq[String] => "\"" + key + "\": " + x.mkString("[", ", ", "]")

而不是这个:

case x: Seq[Map[String, Any]] => x.map(el => beautify(el)).mkString("[", ", ", "]")

我会感激任何帮助。

1 个答案:

答案 0 :(得分:2)

您的case x: Seq[Map[String, Any]]无法访问,因为它与case x: Seq[String]具有相同的运行时类型。构建程序时,擦除Seq中的类型参数。

有几种解决方法 - 我会给你最简单的。首先,将类包装在case类中:

case class SeqMap(value: Seq[Map[String, Any]])

然后您的价值将如下:

val value = Map(
  "items" -> SeqMap(
    Seq(Map(
      "type" -> Seq("http://data-vocabulary.org/Product"),
      "properties" -> Map(
        "brand" -> Seq("Bridgestone"),
        "category" -> Seq("Truck Tires"),
        "name" -> Seq("R-195F"),
        "photo" -> Seq(""),
        "price" -> Seq("$300.09"),
        "url" -> Seq("http://www.bridgestonetrucktires.com")
      )
    ))
  )
)

而且,你的新比赛声明:

case x: Map[String, Any] => ...
case x: Seq[String] => ...
case x: SeqMap => ...

而且,即使如此,由于类型擦除,StringMap[String, Any]中的Seq[String]也会被忽略。例如,Seq[String]Seq[Int]的运行时类型是相同的。

有更多方法可以克服Scala中的类型擦除 - 以上示例是最快捷,最简单的方法。