2016-12-01 3 views
0

Я получаю ответ JSON от восходящего сервера, на который у меня нет контроля, для изменения.Воспроизвести JSON JsPath Условные типы

JSON может иметь следующий формат

{"data":[["Some_text","boolean",["key_string1","key_string2"]]]} 

Или это может также показать, как

{"data":[["Some_text","boolean","key_string2"]]} 

Или это может проявляться в виде комбинации из двух.

{"data":[["Some_text","boolean",["key_string1","key_string2"]],["Some_text","boolean","key_string2"]]} 

Индивидуально я могу определить ЧТЕНИЯ для каждого формата, если они не смешиваются. Однако, учитывая, что данные могут быть смешанного формата, я не могу обернуть голову тем, как следует читать записи, чтобы проверить, не является ли базовый тип строкой или массивом перед его преобразованием?

Можно ли сказать что-то вроде

(
    (JsPath)(0).read[String] and 
    (JsPath)(1).read[Boolean] and 
    (JsPath)(2).read(**if type is simple, String OR if type is array, then seq**) 
)(SomeGloriousCaseClass) 

Как я могу подойти к этой проблеме десериализации?

+0

У меня довольно хорошее представление о том, как это сделать, но можете ли вы связать базовый класс, на который вы хотите его сопоставить? –

+0

Несомненно, я не против формата для базового класса, если он решает проблему десериализации. В настоящее время я использовал следующий класс case 'case class SomeGloriousCaseClass (initialPart: String, booleanPart: Boolean, theDifficultPart: Seq [String])'. Я даже не возражаю, если все преобразуется в последовательность – Serendipity

+0

'(_ \" data "). Читать [JsArray] .flatMap {jsa => ??? } ' – cchantep

ответ

1

Для удовольствия я внедрил решение. Возможно, вам придется немного подкорректировать его:

private def toSeq(jsValue: JsValue): JsResult[Seq[String]] = { 
    jsValue match { 
     case JsArray(es:Seq[JsValue]) ⇒ sequence(es.map(e ⇒ toSeq(jsValue))).map(_.flatten) 
     case JsString(s) ⇒ JsSuccess(s :: Nil) 
     case _ ⇒ JsError("INVALID") 
    } 
    } 

    private def sequence[A](seq:Seq[JsResult[A]]):JsResult[Seq[A]] = { 
    seq.foldLeft(JsResult.applicativeJsResult.pure(Seq[A]()))((acc, next) ⇒ for(acc2 ← acc; next2 ← next) yield acc2 :+ next2) 
    } 

Надеюсь, что это поможет и с удовольствием предоставит вам дополнительные пояснения.

+0

В качестве примечания к сведению, я хотел бы упомянуть, что я повторно реализовал 'последовательность', потому что я понятия не имею, существует один существующий –

+0

Хотя это не то, что я наконец использовал, это помогло мне разобраться, как решить проблему. Спасибо, Луис! – Serendipity

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