我正在使用 Scala 与播放。我有一个 JSON 文件,其中包含世界上所有国家/地区及其各自的城市。 JSON看起来像这样:
{
"CountryA": ["City1","city2"],
"CountryB": ["City1"]
}
我会相应地解析它:
val source: String = Source.fromFile("app/assets/jsons/countriesToCities.json").getLines.mkString
val json: JsValue = Json.parse(source)
我的最终目标是将json
内容转换为Scala MultiMap ,其中键是String
- 国家/地区,值是Set[String]
- cities 。
提前致谢!
答案 0 :(得分:2)
这是一个冗长的解决方案,如果JSON结构与您期望的不匹配,则不会抛出:
val source: String =
"""
|{
| "CountryA": ["City1","city2"],
| "CountryB": ["City1"]
|}
""".stripMargin
val json: JsValue = Json.parse(source)
import scala.collection.breakOut
val map: Map[String, Set[String]] = json.asOpt[JsObject] match {
case Some(obj) =>
obj.fields.toMap.mapValues { v =>
v.asOpt[JsArray] match {
case Some(JsArray(cities)) => cities.flatMap(_.asOpt[String])(breakOut)
case _ => Set.empty[String]
}
}
case _ => Map.empty[String, Set[String]]
}
map must beEqualTo(Map("CountryA" -> Set("City1", "city2"), "CountryB" -> Set("City1")))
如果您对JSON的结构有信心并且不介意使用as
(可以抛出)而不是asOpt
(不会):
val map2: Map[String, Set[String]] = {
json.as[JsObject].fields.toMap.mapValues {
_.as[JsArray].value.map(_.as[String])(breakOut)
}
}
map2 must beEqualTo(Map("CountryA" -> Set("City1", "city2"), "CountryB" -> Set("City1")))