获取 Scala 地图的嵌套字段

get nested fields of Scala map

我有以下地图对象:

val ad = node.asInstanceOf[Map[String, Any]]

广告对象的打印示例是:

ListMap(userId -> 1234, userName -> Jason, location -> ListMap(longitude -> -79.234264, latitude -> 37.2395), email -> Some(jason@yahoo.com))

我正在尝试访问位置字段的嵌套字段并将其转换为双精度值。我有以下内容:

ad.get("location") match {
          case Some(i) => i match {
            case j: Map[Any, Any] => j("longitude").asInstanceOf[Double]
          }

我的问题是还有另一种 graceful/cleaner 语法方式来获取位置字段的嵌套对象吗?

这取决于"graceful/cleaner"的概念,因为那种数据结构不太好闻。

无论如何,内部模式匹配可以与外部模式匹配合并,如下所示:

ad.get("location") match  {
    case Some(i: Map[Any,Any]) => i("longitude").asInstanceOf[Double]
    case _ => // do nothing
}

你不能用像 Map[String, Any] 这样的类型做任何优雅的事情。我首先会考虑使用类型更安全的 Json 库,例如 Circe.

否则,这取决于您对 Map 的静态了解。如果您确定 "location" 存在于 Map 中,并且它总是包含一个带有 "longitude" 键的嵌套 Map,并且 "longitude" 确实是总是一个Double,那么return一个Double就可以了。否则,您应该考虑 returning 一个 Option[Double] 或类似 Either[String, Double] 的东西。例如:

ad.get("location").flatMap {
  case location: Map[String, _] => Try(location("longitude").asInstanceOf[Double]).toOption
  case _ => None
}

如果由于任何原因无法获得所需的值,这将 return 一个 None:"location" 不存在,"location" 不是地图, "location"地图不包含"longitude"等