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
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.