当我解析它返回结构Some(List(Map ...))
时,我有一些json如何与事物匹配并获取值
下面是我尝试的代码,我需要获取所有地图值
import scala.util.parsing.json._
val result = JSON.parseFull("[{\"start\":\"starting\",\"test\":123,\"test2\":324,\"end\":\"ending\"}]")
result match {
case Some(map: Map[String, Any]) => { println(map)
}
case None => println("Parsing failed")
case other => println("Unknown data structure: " + other)
}
但打印不匹配
Unknown data structure: Some(List(Map(start -> starting, test -> 123, test2 -> 324, end -> ending)))
答案 0 :(得分:2)
正如已经指出的,返回类型实际上是Option[List[Map[String, Any]]]
,因此您需要取消选择。但是,由于类型擦除,您不能使用单个match
来执行此操作,因此您需要进行嵌套匹配以确保您具有正确的类型。这确实很繁琐,所以我强烈建议在Extraction.extract
中使用类似json4s
函数的方法,该函数将尝试将JSON与特定的Scala类型进行匹配:
type ResultType = List[Map[String, Any]]
def extract(json: JValue)(implicit formats: Formats, mf: Manifest[ResultType]): ResultType =
Extraction.extract[ResultType](json)
如果必须手动操作,它看起来像这样:
result match {
case Some(l: List[_]) =>
l.headOption match {
case Some(m) =>
m match {
case m: Map[_,_] =>
m.headOption match {
case Some(p) =>
p match {
case (_: String, _) =>
m.foreach(println(_))
case _ => println("Map key was not String")
}
case _ => println("Map was empty")
}
case _ => println("List did not contain a Map")
}
case _ => println("Result List was empty")
}
case _ => println("Parsing failed")
}
答案 1 :(得分:2)
由于类型擦除,您无法对通用类型进行模式匹配。 JavaScript
,List
,Map
是通用容器,在运行时编译器将擦除这些通用容器的类型。例如Option
,List[String]
将被删除,类型将为String
。
List[_]
在上述情况下,如果结果为case Some(map: List[Map[String, Any]]) => println(map)
,即val result: Option[Any] = Some(List(12))
,其类型为12
而不是Int
,则编译器仍将匹配Map[String, Any]
在上述情况下,甚至期望result
为Map[String, Any]]
的类型。
那么,怎么回事?
这都是由于类型擦除所致。除非您使用反射,否则编译器将擦除所有类型,并且在运行时不会包含任何类型信息。这意味着:
List
本质上是case Some(map: List[Map[String, Any]]) => println(map)
,因此,对于case Some(map: List[_]) => println(map)
的任何类型参数(例如, List
,List[Map[String, Any]]
,List[Map[String, Int]]
,List[String]
等。
因此,如果需要在此类通用容器上进行匹配,则必须显式解析每个容器及其嵌套的子类型。
List[Int]
答案 2 :(得分:-2)
您的输出是Option[List[Map[String, Any]]]
,而不是Option[Map[String, Any]]
。在列表上匹配,就可以了:
import scala.util.parsing.json._
val result = JSON.parseFull("[{\"start\":\"starting\",\"test\":123,\"test2\":324,\"end\":\"ending\"}]")
val l: List[Map[String, Any]] = result match {
case Some(list: List[Map[String, Any]]) => list
case _ => throw new Exception("I shouldn't be here") // whatever for a non-match
}
然后,您可以在该列表上map
(如果要使用非单位返回类型)/ foreach
(如果您不在乎单位返回类型)并执行所需的操作:
l.foreach(println)
l.map(_.toString) // or whatever you want ot do with the Map