【问题标题】:How to filter JSON array results based on condition?如何根据条件过滤 JSON 数组结果?
【发布时间】:2019-10-26 09:58:02
【问题描述】:

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

{
  "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 \\ "end").filter(new DateTime(_).isBefore(to.toDate.getTime))...

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

解决方案应该输出结果:

{
  "type": "searchset",
  "total": 3,
  "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"
    }
}

如何使用 Play JSON 做到这一点?

【问题讨论】:

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


    【解决方案1】:

    对于从海岸到海岸的设计,尝试像这样定义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._
    

    【讨论】:

    • 嗨@Mario Galic 再次感谢您!这里故意不使用序列化。我正在外部 JSON API 提供程序之上构建一个 App JSON API 来提供我的 Angular 前端。因此,我的 Play 端是一个传递,如果你知道我的意思,不想序列化它。
    • 赞成这个答案可能对其他可以考虑序列化的人有用。
    • 哇,太棒了,我知道从海岸到海岸的设计可以削减......只是没能弄清楚如何:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-18
    • 2022-01-23
    • 2018-10-04
    • 2021-04-19
    • 1970-01-01
    • 2021-04-10
    • 2021-01-03
    相关资源
    最近更新 更多