考虑供应商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)
答案 0 :(得分:3)
这是我如何用漂亮的可组合部分构建这个解析器。首先是用于丢弃密钥的通用对象到数组变换器:
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))
这是你想要的。请注意,为了清楚起见,我已经指定了上面的类型,但这里没有必要 - 我可能会将它们留在实际代码中,因为这些部分非常小而直接。