2017-11-08 1 views
1

Ich habe folgende JSON in JsArray (oder String) in Scala.Wie analysiert man JsArary in scala?

[ 
    { 
    "row1": [ 
     { 
     "seatId": "R1", 
     "seatStatus": "BOOKED", 
     "seatIsLadies": false 
     }, 
     { 
     "seatId": "R3", 
     "seatStatus": "AVAILABLE", 
     "seatIsLadies": false 
     } 
    ] 
    }, 
    { 
    "row2": [ 
     { 
     "seatId": "R1", 
     "seatStatus": "BOOKED", 
     "seatIsLadies": false 
     }, 
     { 
     "seatId": "R3", 
     "seatStatus": "AVAILABLE", 
     "seatIsLadies": false 
     } 
    ] 
    }, 
    { 
    "row3": [ 
     { 
     "seatId": "R1", 
     "seatStatus": "BOOKED", 
     "seatIsLadies": false 
     }, 
     { 
     "seatId": "R3", 
     "seatStatus": "AVAILABLE", 
     "seatIsLadies": false 
     }, 
     { 
     "seatId": "R3", 
     "seatStatus": "AVAILABLE", 
     "seatIsLadies": false 
     } 
    ] 
    } 
] 

wo row1, row2, row3 nach variieren können anrufen, manchmal kann es row1-5 oder vielleicht row1-4 sein. Wie kann ich diesen JSON analysieren? Wie kann ich row1, row2 und so weiter extrahieren?

Antwort

3

Die Idee ist es, das Array als Vector[JsObject] und dann zu verwenden, was den Schlüssel (row1, row2, row3, ...) ist, als ein Feld in einem Fall Klasse parsen und die innere Matrix als eine Vector der Sitze parsen .

Für den folgenden Code, bitte beachten Sie, dass ich keine Fehlerbehandlung! Sie möchten nicht nur die .as Methode verwenden, sondern stattdessen zum Beispiel validate und das gleiche gilt für die unsichere .head Aufruf beim Aufbau der Klasse. Having said that,

hier ein Ammoniten Skript, das genau das tut:

import $ivy.`com.typesafe.play::play-json:2.6.7` 

import play.api.libs.json._ 

case class Row(name: String, seats: Vector[Seat]) 

case class Seat(seatId: String, seatStatus: String, seatIsLadies: Boolean) 

object Seat { 
    implicit def format: Format[Seat] = Json.format[Seat] 
} 

    val inputJson = """ 
[ 
    { 
    "row1": [ 
     { 
     "seatId": "R1", 
     "seatStatus": "BOOKED", 
     "seatIsLadies": false 
     }, 
     { 
     "seatId": "R3", 
     "seatStatus": "AVAILABLE", 
     "seatIsLadies": false 
     } 
    ] 
    }, 
    { 
    "row2": [ 
     { 
     "seatId": "R1", 
     "seatStatus": "BOOKED", 
     "seatIsLadies": false 
     }, 
     { 
     "seatId": "R3", 
     "seatStatus": "AVAILABLE", 
     "seatIsLadies": false 
     } 
    ] 
    }, 
    { 
    "row3": [ 
     { 
     "seatId": "R1", 
     "seatStatus": "BOOKED", 
     "seatIsLadies": false 
     }, 
     { 
     "seatId": "R3", 
     "seatStatus": "AVAILABLE", 
     "seatIsLadies": false 
     }, 
     { 
     "seatId": "R3", 
     "seatStatus": "AVAILABLE", 
     "seatIsLadies": false 
     } 
    ] 
    } 
] 
""" 

val json = Json.parse(inputJson) 

val rowObjs = json.as[Vector[JsObject]] 

val result = rowObjs.map(obj => Row(obj.fields.head._1, obj.fields.head._2.as[Vector[Seat]])) 

println(result) 

, die in der Ausgabe führt:

Vector(
    Row(row1,Vector(Seat(R1,BOOKED,false), Seat(R3,AVAILABLE,false))), 
    Row(row2,Vector(Seat(R1,BOOKED,false), Seat(R3,AVAILABLE,false))), 
    Row(row3,Vector(Seat(R1,BOOKED,false), Seat(R3,AVAILABLE,false),Seat(R3,AVAILABLE,false))) 
) 
1

können Sie verwenden recursive path operator \\

import play.api.libs.json._ 

case class RowValue(seatId: String, seatStatus: String, seatIsLadies: Boolean) 
object RowValue { 
    implicit val rowFormat: Format[RowValue] = Json.using[Json.WithDefaultValues].format[RowValue] 
} 
// in json is your json string 
val js: JsValue = Json.parse(json) 
val rowNames: Seq[String] = Seq[String]("row1", "row2", "row3", "row4", "row5") 
rowNames.foreach { r => 
    val rowValues = (js \\ r).map(x => x.asOpt[Seq[RowValue]]) 
    println(s"$r => $rowValues") 
} 

Ausgang wird sein:

row1 => ArrayBuffer(Some(List(RowValue(R1,BOOKED,false), RowValue(R3,AVAILABLE,false)))) 
row2 => ArrayBuffer(Some(List(RowValue(R1,BOOKED,false), RowValue(R3,AVAILABLE,false)))) 
row3 => ArrayBuffer(Some(List(RowValue(R1,BOOKED,false), RowValue(R3,AVAILABLE,false), RowValue(R3,AVAILABLE,false)))) 
row4 => ArrayBuffer() 
row5 => ArrayBuffer()