Question

I tried the tutorial of json spray but i have a different string where one value is a string and the other one is a list. How do i convert the following string into a json object where each key is either a list or a string?

source = """{ "some": "JSON source", "kuku":["fu"] }"""

I wrote a short snipped of code but cannot continue from here:

val source = """{ "some": "JSON source", "kuku":["fu"] }"""
val jsonAst = source.asJson
val kuku = jsonAst.convertTo[?]
println(kuku)

If i cannot, how do i get the value of the key some(hopefully without regular expression) I would prefer to avoid creating a specific object for it, because there are certain keys which can change.

Thanks, David

Was it helpful?

Solution

You can convert the entire object to a map to an Either:

val jsonMap = jsonAst.convertTo[Map[String, Either[String, List[String]]]]

And then:

scala> println(jsonMap)
Map(some -> Left(JSON source), kuku -> Right(List(fu)))

The Either part explicitly models the fact that you don't know at compile-time which kind of value you'll get when you look up a key. There are lots of introductions to the idea of Either in Scala, but in short you can use it like this:

val some: String = jsonMap("some").left.getOrElse(
  ??? /* Provide a default value, throw an exception, etc. */
)

val kuku: List[String] = jsonMap("kuku").right.getOrElse(
  ??? /* Provide a default value, throw an exception, etc. */
)

Or, even better, handle the fact that the key might not exist at the same time:

val some: String = jsonMap.get("some").flatMap(_.left.toOption).getOrElse(
  ??? /* Provide a default value, throw an exception, etc. */
)

Alternatively you could navigate to the "kuku" field and then convert:

val kuku = jsonAst.asJsObject.getFields("kuku").headOption.map(
  _.convertTo[List[String]]
)

And then:

scala> kuku
res0: Option[List[String]] = Some(List(fu))

I personally find the first approach a little cleaner.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top