mzbaran
mzbaran

Reputation: 624

How to call Map functions on object that returns Map with type Any in Scala

I have a function that returns an Any value where the actual value is a Map like

Any = Map(EFO -> [{"invalidPositions":false,"ft":false,"synState":[1]}]

This makes the compiler complain when I try to call methods of the Map class on the resultant object. How can I cast this object in such a way that I can call methods of the Map class?

Upvotes: 0

Views: 184

Answers (1)

lprakashv
lprakashv

Reputation: 1159

As you mentioned abvoe that you ended up with an Any value by using ujson library, so, this problem is more specific to that particular library. You can solve your problem using this approach:

import upickle

val s = """
{
    "url": "https://api.github.com/repos/lihaoyi/Ammonite/releases/17991367",
    "assets_url": "https://api.github.com/repos/lihaoyi/Ammonite/releases/17991367/assets",
    "upload_url": "https://uploads.github.com/repos/lihaoyi/Ammonite/releases/17991367/assets{?name,label}"
}"""

upickle.default.read[Map[String, String]](s)

Note: If you want to resolve the parsed json value to a particular scala case class you have to define an impilict for read/write like:

case class Rec(url: String, assets_url: String, upload_url: String)

implicit val recRW = upickle.default.macroRW[Rec]

upickle.default.read[Rec](s)

Here is the ammonite repl output:

@ s
res10: String = """
{
    "url": "https://api.github.com/repos/lihaoyi/Ammonite/releases/17991367",
    "assets_url": "https://api.github.com/repos/lihaoyi/Ammonite/releases/17991367/assets",
    "upload_url": "https://uploads.github.com/repos/lihaoyi/Ammonite/releases/17991367/assets{?name,label}"
}"""

@ upickle.default.read[Map[String, String]](s)
res11: Map[String, String] = Map(
  "url" -> "https://api.github.com/repos/lihaoyi/Ammonite/releases/17991367",
  "assets_url" -> "https://api.github.com/repos/lihaoyi/Ammonite/releases/17991367/assets",
  "upload_url" -> "https://uploads.github.com/repos/lihaoyi/Ammonite/releases/17991367/assets{?name,label}"
)

@ upickle.default.read[Rec](s)
res12: Rec = Rec(
  "https://api.github.com/repos/lihaoyi/Ammonite/releases/17991367",
  "https://api.github.com/repos/lihaoyi/Ammonite/releases/17991367/assets",
  "https://uploads.github.com/repos/lihaoyi/Ammonite/releases/17991367/assets{?name,label}"
)

Reference: https://www.lihaoyi.com/post/HowtoworkwithJSONinScala.html

Upvotes: 2

Related Questions