Search code examples
scalareflectiontype-variables

How to know type of Map value Map("key->"value") in Scala?


I have an issue with a value of Map("id"), its could have two types : String or Map[String,String].

Case 1: val a = Map("id" -> "123")
Case 2: val a = Map("id"-> Map("ide"->"abcd"))

I want to do a check with a Match case like this :

def d = a.get("id") match {

  case _:String => "String"
  case _:Map[String,Any] => "Map"


}

Does anyone have an idea of how should I handle this case??


Solution

  • Sightly modified from Dmitry's answer. This code snippet uses TypeTag to Overcome type erasure.

    import scala.reflect.runtime.universe.{TypeTag, typeOf}
    
    def d[T](map: Map[String, T])(implicit T: TypeTag[T]) = map.get("id") match {
      case Some(_) if T == typeOf[String] => "String"
      case Some(_) if T == typeOf[Map[String, String]] => "Map[String, String]"
      case Some(_) => "Other"
      case None => "Not found"
    }
    
    d(Map("id" -> "Hello")) // String.
    d(Map("id" -> Map("Hello" -> "World"))) // Map[String, String].
    d(Map("id" -> 10)) // Other.
    d(Map("id" -> Map(10 -> true))) // Other.
    d(Map.empty) // Not found.
    

    Note, this will only work if all elements of the Map have the same type when the method is called...
    If you have a Map[String, Any] in the first place, this becomes more complicated - and probably Dmitry answers would be better.