Search code examples
scalascala-2.11

How to get value from nested map of type AnyRef


So I have a map of type

Map[String, AnyRef]

When I print this map through println, it gives the following output

Map(revision -> 
 Map(comment -> "string1", 
     contributor -> Map(id -> "int1", username -> "string2"), 
     format -> "string3", 
     id -> "int2", 
     minor -> None, 
     model -> "string4", 
     parentid -> "int3", 
     sha1 -> "string5", 
     text -> Map(_VALUE -> "VALUE-THAT-I-WANT-TO-GET", 
     space -> ""), 
     timestamp -> Timestamp, 
     title -> "string6"))

Now as you see in the map, I want to get the value against key _VALUE.

I tried getting it the way you get from a nested map explained in this answer, but it didn't work may be because it's of type AnyRef
What is the best way to get it in a simple string variable?

I am sorry if map is not readable enough, I will accept if you edit it in a better way. But it had be posted complete to clear sense of the problem.


Solution

  • So let's say you have a coworker that produces code like that. Of course that person gets fired for being incompetent. Alas, you get stuck with the task of working with it until it can be rewritten into proper Scala.

    Here's one thing you might do. It compiles with a warning but appears to produce the desired result.

    def extract(m :collection.Map[String,AnyRef], key :String) :Option[String] = {
      if (m.isDefinedAt(key)) Some(m(key).toString)
      else {
        val res = m.values
                   .collect{case ma:Map[String,AnyRef] => extract(ma,key)}
                   .dropWhile(_.isEmpty)
        if (res.isEmpty) None else res.head
      }
    }
    
    extract(badMap, "_VALUE") //res0: Option[String] = Some(VALUE-THAT-I-WANT-TO-GET)
    extract(badMap, "_XALUE") //res1: Option[String] = None