Apply key to map obtained via pattern matching in Scala (type erased)

101 views Asked by At

I am trying to query an API which returns a JSON array (e.g. [{"name":"obj1", "value":5}, {"name":"obj2", "value":2}]) and process the result, which gets parsed as an Option[List[Map[String,Any]]]. However, I am not sure how to properly extract each Map, since the types are erased at runtime.

import scala.util.parsing.json._
import scalaj.http._

val url = "https://api.github.com/users/torvalds/repos"
val req = Http(url).asString

val parsed = JSON.parseFull(req.body) match {
  case Some(data) => data match {
    case list: List[_] => list
    case _ => sys.error("Result is not a list.")
  }
  case None => sys.error("Invalid JSON received.")
}

parsed.foreach{
  case x: Map[_,_] => x.get("full_name") // error here
}

The error occurs because I cannot apply the function with a String key type. However, because of type erasure, the key and value type are unknown, and specifying that it's a String map throws compiler warnings.

Am I going about things the wrong way? Or maybe I'd have better luck with a different HTTP/JSON library?

1

There are 1 answers

2
marios On BEST ANSWER

You can replace your last line with:

parsed.collect{ case x: Map[_,_] => x.asInstanceOf[Map[String,Any]].get("full_name") }

We sort of "cheat" here since we know the keys in a JSON are always Strings.

As for your last question, if you need something lightweight, I think what you have here is as simple as it gets.


Take a look at this SO post if you want to do something more powerful with your pattern matching.