Scala 使用JSON字符串中的嵌套映射
给定如下JSON字符串:Scala 使用JSON字符串中的嵌套映射,scala,Scala,给定如下JSON字符串: {"Locations": {"list": [ {"description": "some description", "name": "the name", "id": "dev123"}, {"description": "other description", "name": "other name", "id": "dev59"} ] } } 我想从解析上述字符串的函数返回一个“id”列表JSON.parseF
{"Locations":
{"list":
[
{"description": "some description", "name": "the name", "id": "dev123"},
{"description": "other description", "name": "other name", "id": "dev59"}
]
}
}
我想从解析上述字符串的函数返回一个“id”列表JSON.parseFull()
(来自scala.util.parsing.JSON
)为我提供类型为Option[Any]
的结果。Scala REPL将其显示为Some(地图位置->地图(列表->列表)(地图(id->dev123,…
),作为Scala的初学者,我不知道该怎么做
建议“将其视为一个集合或monad并使用map、flatMap、filter或foreach”。顶层元素是一个选项[Any],但是应该是一个包含单键“Locations”的映射,该映射应该包含一个单键“list”最后是一个列表。在Scala中,编写函数检索“id”的惯用方法是什么?这就是您需要的吗?(使用lift json)
由于返回的结果是Any is everywhere,因此您必须强制转换。请使用以下方法之一:
class CC[T]{def unapply(a:Any):Option[T]=Some(a.asInstanceOf[T])]
对象M扩展CC[Map[String,Any]]
对象L扩展CC[列表[任何]]
对象S扩展CC[String]
对象D扩展CC[Double]
对象B扩展CC[布尔值]
为了{
一些(M(map))首先,您应该将json从任意类型转换为正确类型:
val json = anyJson.asInstanceOf[Option[Map[String,List[Map[String,String]]]]]
然后,您可以使用map
方法从选项中提取ID:
val ids = json.map(_("Locations")("list").map(_("id"))).getOrElse(List())
对于这类任务,您应该看一看。我也是scala初学者,但从我搜索的内容来看,这似乎是最友好的语法。下面是一个简短的示例,取自:
在JSON之子的一个分支中,这将起作用。请注意,我没有使用解析器。并不是说它不存在。只是使用生成器方法创建JSON对象更容易:
scala> import nl.typeset.sonofjson._
import nl.typeset.sonofjson._
scala> var all = obj(
| locations = arr(
| obj(description = "foo", id = "807",
| obj(description = "bar", id = "23324"
| )
| )
scala> all.locations.map(_.id).as[List[String]]
res2: List[String] = List(23324, 807)
或使用一个字母来理解:
scala> (for (location <- all.locations) yield location.id).as[List[String]]
res4: List[String] = List(23324, 807)
scala>(对于(位置),我认为类型不完整-当我使用anyJson.asInstanceOf[Option[Map[String,Map[String,List[Map[String,String]].][
。它是如何工作的呢?asInstanceOf
是我读到的一个运行时强制转换。我假设当给定的任何对象不同时,它会抛出一个异常。顺便问一下,映射了什么(“位置”)(“列表”)…
mean?是的,asInstanceOf
将抛出异常。但是,由于JVM中的类型擦除,map(u(“位置”)(“列表”)。map((“id”)
是map(x=>x(“Locactions”)(“列表”)的快捷方式。map((“id”)
方法map
转换容器的内部值(Option
在本例中)使用给定函数。给定函数接收一个Map
的Map
并从中检索值(两层深)-它是包含id的映射列表。因此,.Map(uU(“id”)
通过从每个元素(即Map”)检索“id”值,将映射列表转换为id列表[String,String]
谢谢。不过看起来比其他答案更复杂。net.liftweb.json
建议使用第三方库(我想是从Lift框架中)@FilipK:lift json是一个单独的包。你不必将整个lift框架拉入你的项目中。我对它很陌生。当然,一定有一种更简单的lift json方法来做你想做的事情。
import rapture.io._
// Let's parse some JSON
val src: Json = Json.parse("""
{
"foo": "Hello world",
"bar": {
"baz": 42
}
}
""")
// We can now access the value bar.baz
val x: Json = src.bar.baz
// And get it as an integer
val y: Int = x.get[Int]
// Alternatively, we can use an extractor to get the values we want:
val json""" { "bar": { "baz": $x }, "foo": $z }""" = src
// Now x = 42 and z = "Hello world".
scala> import nl.typeset.sonofjson._
import nl.typeset.sonofjson._
scala> var all = obj(
| locations = arr(
| obj(description = "foo", id = "807",
| obj(description = "bar", id = "23324"
| )
| )
scala> all.locations.map(_.id).as[List[String]]
res2: List[String] = List(23324, 807)
scala> (for (location <- all.locations) yield location.id).as[List[String]]
res4: List[String] = List(23324, 807)