2013-11-20 1 views
4

Я пробовал учебник json spray, но у меня есть другая строка, где одно значение - это строка, а другая - список. Как преобразовать следующую строку в объект json, где каждый ключ является либо списком, либо строкой?Как преобразовать json со значениями смешанного типа в json с scala и json spray

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

я написал короткий отрезала кода, но не может продолжать здесь:

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

Если я не могу, как я могу получить значение ключа какой-то (надеюсь, без регулярного выражения) я бы предпочитают избегать создания для него определенного объекта, потому что есть определенные ключи, которые могут измениться.

Спасибо, David

ответ

3

Вы можете преобразовать весь объект на карту к Either:

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

А потом:

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

Either часть в явном виде моделирует тот факт, что вы не знаете во время компиляции, какую ценность вы получите, когда будете искать ключ. Есть много introductions к идее Either в Scala, но вкратце вы можете использовать его как это:

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. */ 
) 

Или, еще лучше, справиться с тем, что ключ не может существовать одновременно:

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

в качестве альтернативы вы могли бы перейти к "kuku" поле, а затем конвертировать:

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

а потом:

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

Я лично считаю, что первый подход немного чище.

+0

Спасибо за отличное объяснение. Как я могу получить значение «источник JSON» без левого? println (jsonMap.get («kuku»). get) дает мне Left («Источник JSON») –

+0

Я только что добавил несколько комментариев о 'Either'. –

Смежные вопросы