0

I have a JSON string, say:

val json = JSONObject(Map("a" -> 1)).toString()

I want to convert this json to map again. I tried:

val map = json.toMap[String, Int]

This gives me the following error:

Error:(46, 25) Cannot prove that Char <:< (String, Int).
val map = json.toMap[String, Int]
                    ^
Error:(46, 25) not enough arguments for method toMap: (implicit ev: <:<[Char,(String, Int)])scala.collection.immutable.Map[String,Int].
Unspecified value parameter ev.
val map = json.toMap[String, Int]
                    ^

What is the correct way of doing this?

nish
  • 6,952
  • 18
  • 74
  • 128

3 Answers3

1
val map = json.toMap.asInstanceOf[Map[String, Int]]
renzherl
  • 161
  • 1
  • 3
  • This causes me the same error as in the OP. Also, this answer needs a bit more context, why should it work, etc. – Lucas Lima Dec 04 '19 at 19:34
0

Using play-json you can convert Json to Map using validate. Validate returns JsResult which can be JsSuccess(data,path) or JsError(errors). Pattern match to get the map out of it.

If you are using sbt project then add play-json dependency to your project.

build.sbt

libraryDependencies ++= Seq("com.typesafe.play" %% "play-json" % "2.54.")

Scala REPL

scala> import play.api.libs.json._
import play.api.libs.json._

scala> val map = Map("java" -> 1, "scala" -> 2)
map: scala.collection.immutable.Map[String,Int] = Map(java -> 1, scala -> 2)

scala> Json.toJson(map).validate[Map[String, Int]]
res3: play.api.libs.json.JsResult[Map[String,Int]] = JsSuccess(Map(java -> 1, scala -> 2),)

scala> val result = Json.toJson(map).validate[Map[String, Int]]
result: play.api.libs.json.JsResult[Map[String,Int]] = JsSuccess(Map(java -> 1, scala -> 2),)

scala> result match { case JsSuccess(data, _) => data case JsError(errors) => Unit}
res4: Object = Map(java -> 1, scala -> 2)
Nagarjuna Pamu
  • 14,737
  • 3
  • 22
  • 40
0

If this is a one-off then you could do something like this:

  val json = JSONObject(Map("a" -> 1)).toString() //> json  : String = {"a" : 1}

  val map = json.substring(1, json.length - 1).split(":").map(_.trim) match {
    case Array(s: String, i: String) => Map(s -> i.toInt)
  }                                               //> map  : scala.collection.immutable.Map[String,Int] = Map("a" -> 1)

However, if you are doing more with Json then you probably want to explore the use of a library since I think the support for Json in the standard library is limited. See this post for a good overview of available libraries.

Community
  • 1
  • 1
jacks
  • 4,614
  • 24
  • 34