4

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

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the great explaination. How do i get to the value "JSON source" without the Left? println(jsonMap.get("kuku").get) gives me Left("JSON source")
I've just added some comments about Either.

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.