2017-11-08 5 views
1

私はScalaのJsArray(またはString)に次のJSONを持っています。スカラでJsAraryを解析するには?

[ 
    { 
    "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 
     } 
    ] 
    } 
] 

ここで、row1、row2、row3はコールによって異なる場合があります。row1-5またはrow1-4の場合もあります。このJSONをどのように解析できますか? row1、row2などをどのように抽出できますか?

答えて

3

アイデアはVector[JsObject]として配列を解析し、ケースクラスのフィールドとしてである(ROW1、ROW2、ROW3、...)どんなキーを使用し、座席のVectorように、内側の配列を解析することです。

を処理していませんでした。 .asメソッドを使用するだけでなく、代わりにvalidateを使用して、クラスを構築するときに安全でない.headコールの場合も同じです。

出力になり
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) 

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

あなたは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") 
} 

出力を使用することができ、ここで

はまさにそのアンモナイトスクリプトである、と述べました

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() 
関連する問題