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?

3 Answers 3

1
val map = json.toMap.asInstanceOf[Map[String, Int]]
Sign up to request clarification or add additional context in comments.

1 Comment

This causes me the same error as in the OP. Also, this answer needs a bit more context, why should it work, etc.
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)

Comments

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.