Reputation: 3064
Whats the best way to handle generics and erasure when doing pattern matching in Scala (a Map in my case). I am looking for a proper implementation without compiler warnings. I have a function that I want to return Map[Int, Seq[String]] from. Currently the code looks like:
def teams: Map[Int, Seq[String]] = {
val dateam = new scala.collection.mutable.HashMap[Int, Seq[String]]
// data.attributes is Map[String, Object] returned from JSON parsing (jackson-module-scala)
val teamz = data.attributes.get("team_players")
if (teamz.isDefined) {
val x = teamz.get
try {
x match {
case m: mutable.Map[_, _] => {
m.foreach( kv => {
kv._1 match {
case teamId: String => {
kv._2 match {
case team: Seq[_] => {
val tid: Int = teamId.toInt
dateam.put(tid, team.map(s => s.toString))
}
}
}
}
})
}
}
} catch {
case e: Exception => {
logger.error("Unable to convert the team_players (%s) attribute.".format(x), e)
}
}
dateam
} else {
logger.warn("Missing team_players attribute in: %s".format(data.attributes))
}
dateam.toMap
}
Upvotes: 1
Views: 1201
Reputation: 297275
Use a Scala library to handle it. There are some based on Jackson (Play's ScalaJson, for instance -- see this article on using it stand-alone), as well as libraries not based on Jackson (of which my preferred is Argonaut, though you could also go with Spray-Json).
These libraries, and others, solve this problem. Doing it by hand is awkward and prone to errors, so don't do it.
Upvotes: 2
Reputation: 434
It could be reasonable to use for
comprehension (with some built in pattern matching). Also we could take into account that Map
is a list of tuples, in our case of (String, Object)
type. As well we will ignore for this example probable exceptions, so:
import scala.collection.mutable.HashMap
def convert(json: Map[String, Object]): HashMap[Int, Seq[String]] = {
val converted = for {
(id: String, description: Seq[Any]) <- json
} yield (id.toInt, description.map(_.toString))
HashMap[Int, Seq[String]](converted.toSeq: _*)
}
So, our for
comprehension taking into account only tuples with (String, Seq[Any])
type, then combines converted String
to Int
and Seq[Any]
to Seq[String]
. And makes Map
to be mutable.
Upvotes: 1