如何根据条件过滤JSON数组结果?

时间:2019-06-11 23:28:32

标签: json scala playframework play-json play-framework-2.7

我正在使用Scala Play 2.7.2,并已阅读ScalaJsonTransformersScalaJson。调用JSON API之后,我得到如下的(简化的MCVE)结果:

question_list2 = []

question_list2.append(" the marines are ___ based opreatives  ")
question_list2.append(" for under water travel marines use _____ ")
question_list2.append(" the avergae marine trains for _ weeks ")

answer_list2 = []

answer_list2.append("sea")
answer_list2.append("subamrines")
answer_list2.append("13")

top_index = 4
correct = 0

for i in range (0,4):

    random_int = random.randint(0,top_index)

    print(question_list2[random_int])

    top_index = top_index - 1

    user_answer1 = input("fill in the blank with the correct word ")

    if user_answer == answer_list1[random_int]:

        correct = correct + 3

    del question_list1[random_int]
    del answer_list1[random_int]

并且我想过滤结果并仅选择那些满足条件的结果,例如,过滤出那些结束日期大于特定日期{ "type": "searchset", "total": 5, "entry": [ { "start": "2019-06-07T09:00:00", "end": "2019-06-07T11:00:00", "id": "55" }, { "start": "2019-06-07T13:00:00", "end": "2019-06-07T15:00:00", "id": "56" }, { "start": "2019-06-07T16:00:00", "end": "2019-06-07T17:00:00", "id": "60" }, { "start": "2019-06-10T11:00:00", "end": "2019-06-10T12:00:00", "id": "58" }, { "start": "2019-06-11T14:00:00", "end": "2019-06-11T15:00:00", "id": "61" } ] } 的结果,然后做一些事情:

val to = new DateTime("2019-06-10T00:00:00")

但是这不起作用,因为结果是选择而不是整个json节点,而且它也离开了外部。

解决方案应输出结果:

(json \\ "end").filter(new DateTime(_).isBefore(to.toDate.getTime))...

如何使用Play JSON完成此操作?

1 个答案:

答案 0 :(得分:2)

对于从海岸到海岸的设计,请尝试像这样定义update transformer

val to = new DateTime("2019-06-10T00:00:00")

val endDateFilterTransformer = (__ \ 'entry).json.update(__.read[JsArray].map {
  case JsArray(values) => JsArray(values.filter(v => (v \ "end").as[DateTime].isBefore(to)))
})

val outJson = json.transform(endDateFilterTransformer)
println(outJson.get)

输出

{
  "entry": [
    {
      "start": "2019-06-07T09:00:00",
      "end": "2019-06-07T11:00:00",
      "id": "55"
    },
    {
      "start": "2019-06-07T13:00:00",
      "end": "2019-06-07T15:00:00",
      "id": "56"
    },
    {
      "start": "2019-06-07T16:00:00",
      "end": "2019-06-07T17:00:00",
      "id": "60"
    }
  ],
  "total": 5,
  "type": "searchset"
}

对于从JSON到OO的设计,也可以尝试反序列化为模型

case class Entry(start: DateTime, end: DateTime, id: String)
object Entry {
  implicit val format = Json.format[Entry]
}
case class Record(`type`: String, total: Int, entry: List[Entry])

object Record {
  implicit val format = Json.format[Record]
}

然后使用常规Scala方法进行过滤

val to = new DateTime("2019-06-10T00:00:00")
val record = Json.parse(raw).as[Record]
val filteredRecord = record.copy(entry = record.entry.filter(_.end.isBefore(to)))

然后像这样反序列化回json:

Json.toJson(filteredRecord)

输出

{
  "type": "searchset",
  "total": 5,
  "entry": [
    {
      "start": "2019-06-07T09:00:00.000+01:00",
      "end": "2019-06-07T11:00:00.000+01:00",
      "id": "55"
    },
    {
      "start": "2019-06-07T13:00:00.000+01:00",
      "end": "2019-06-07T15:00:00.000+01:00",
      "id": "56"
    },
    {
      "start": "2019-06-07T16:00:00.000+01:00",
      "end": "2019-06-07T17:00:00.000+01:00",
      "id": "60"
    }
  ]
}

我们使用play-json-joda进行DateTime序列化

libraryDependencies += "com.typesafe.play" %% "play-json-joda" % "2.7.3"
import play.api.libs.json.JodaWrites._
import play.api.libs.json.JodaReads._