如何使用JsPath遍历JSON对象字段?

如何使用JsPath遍历JSON对象字段?,json,scala,playframework,Json,Scala,Playframework,考虑供应商API提供的以下JSON: import play.api.libs.json._ import play.api.libs.json.Reads._ import play.api.libs.functional.syntax._ val json = Json.parse( """ |{ | "returns": { | "markets" : { | "ABC" : { | "label": "ABC"

考虑供应商API提供的以下JSON:

import play.api.libs.json._
import play.api.libs.json.Reads._
import play.api.libs.functional.syntax._

val json = Json.parse(
  """
    |{
    |  "returns": {
    |    "markets" : {
    |      "ABC" : {
    |        "label": "ABC",
    |        "id":1
    |      },
    |      "DEF" : {
    |        "label": "DEF",
    |        "id":2
    |      }
    |    }
    |  }
    |}
  """.stripMargin)
如何提取与“标签”和“id”字段相关的对序列。 从这段JSON中,我期待的结果是:

Seq((1,"ABC"),(2,"DEF"))
我无法构造正确的JsPath提取器,因为它需要一个匹配项,例如

val jsonTransformer = (__ \ 'returns \ 'markets).json.pick
json.transform(jsonTransformer)

下面是我如何用漂亮的可组合片段构建这个解析器。首先,对于丢弃密钥的通用对象到阵列转换器:

val objToArray: Reads[JsArray] =
  JsPath.json.pickBranch.map(obj => JsArray(obj.fields.map(_._2)))
现在,对于一个可以处理市场对象的
Reads

val marketReads: Reads[(Int, String)] =
  ((__ \ 'id).read[Int] and (__ \ 'label).read[String]).tupled
现在,我们将所有这些联系在一起:

val pairsReads: Reads[List[(Int, String)]] = 
  (__ \ 'returns \ 'markets).read(objToArray) andThen list(marketReads)
最后:

scala> json.validate(pairsReads).foreach(println)
List((1,ABC), (2,DEF))

这就是你想要的。请注意,为了清晰起见,我已经指定了上面的类型,但这里没有必要这样做——我可能会在实际代码中忽略它们,因为这些片段非常小且简单。

这正是我想要的。实际上,第一条指令是我找不到的。那是超杠杆。非常感谢。