繁体   English   中英

如何在Scala中解析JsArary?

[英]How to parse JsArary in scala?

我在Scala的JsArray(或String)中有以下JSON。

[
  {
    "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会根据调用而变化,有时可能是1-5行,或者可能是1-4行。 如何解析此JSON? 如何提取row1,row2等?

这样做是为了解析阵列作为Vector[JsObject]然后使用任何键(ROW1,ROW2,ROW3,...)是作为的情况下类中的字段Row ,并解析内阵列作为Vector的座位。

对于以下代码,请注意我没有错误处理 您不希望仅使用.as方法,而要使用例如validate并且在构建Row类时,对于不安全的.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)))
)

您可以使用递归路径运算符\\\\

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()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM