Reputation: 1075
I have the following Map Object :
val ad = node.asInstanceOf[Map[String, Any]]
and a printed example of ad object is:
ListMap(userId -> 1234, userName -> Jason, location -> ListMap(longitude -> -79.234264, latitude -> 37.2395), email -> Some([email protected]))
I am trying to access the nested fields of the location field and cast it as a double. I have the following:
ad.get("location") match {
case Some(i) => i match {
case j: Map[Any, Any] => j("longitude").asInstanceOf[Double]
}
My question is there another more graceful/cleaner syntax way to get the nested objects of the location field?
Upvotes: 1
Views: 839
Reputation: 810
You can't really do anything graceful with a type like Map[String, Any]
. I would consider using a more type-safe Json library in the first place, such as Circe.
Otherwise, it depends on what you know statically about your Map
. If you know for certain that "location" exists in the Map
, and that it always contains a nested Map
with the "longitude" key, and that "longitude" is indeed always a Double
, then it's OK to return a Double
. Otherwise, you should consider returning an Option[Double]
or something like Either[String, Double]
. For example:
ad.get("location").flatMap {
case location: Map[String, _] => Try(location("longitude").asInstanceOf[Double]).toOption
case _ => None
}
This will return a None
if the desired value cannot be obtained for whatever reason: "location" doesn't exist, "location" is not a map, the "location" map does not contain "longitude", etc.
Upvotes: 0
Reputation: 907
It depends on the concept of "graceful/cleaner" because that kind of data structure doesn't smell good.
Anyway, the inner pattern match can be merged with the outer one, like this:
ad.get("location") match {
case Some(i: Map[Any,Any]) => i("longitude").asInstanceOf[Double]
case _ => // do nothing
}
Upvotes: 2