简体   繁体   English

Scala Play Json中的数组的JsPath

[英]JsPath to array in Scala Play Json

import play.api.libs.json._

val json: JsValue = Json.parse("""
  {
    "name" : "Independence",
    "foundingFathers" : [ {
      "name" : {
        "first": "John",
        "last": "Adams"
      },
      "country" : "United States"
    }, {
      "name" : {
        "first": "Artur",
        "last": "Mas"
      },
      "country" : "Catalonia"
    } ]
  }
""")

val lastNames = json \ "foundingFathers \ "name" \ "last"
// this does not work. it fails with: JsUndefined('last' is undefined on object: JsUndefined('name' is undefined on object: [{"name":{"first":"John","last":"Adams"},"country":"United States"},{"name":{"first":"Artur","last":"Mas"},"country":"Catalonia"}]))

// this does work, but there is too much boilerplate
val lastNames = (json \ "foundingFathers").as[List[JsObject]].map(_ \ "name" \ "last")

how to achieve the result without that boilerplate? 没有样板怎么实现结果? (in this case I want to use JsValues, I don't want to use a reader to convert JsValue to a model) (在这种情况下,我想使用JsValues,我不想使用阅读器将JsValue转换为模型)

You can use implicit classes for wrap it with this functionality 您可以使用隐式类将此功能包装起来

implicit class JsValueWrapper(val j: JsValue) extends AnyVal {
  def \|(fieldName: String) = j match {
    case JsArray(value) => JsArray(value.map(_ \ fieldName))
    case _ => j \ fieldName
  }
}

scala> json \| "foundingFathers" \| "name" \| "first"
res19: play.api.libs.json.JsValue = ["John","Artur"]

minor improvement, not sure whether it answers your question 小改进,不确定是否能回答您的问题

val lastNames = json \ "foundingFathers" \\ "name" map ( _ \ "last")

lastNames: Seq[play.api.libs.json.JsValue] = ListBuffer("Adams", "Mas") lastNames:Seq [play.api.libs.json.JsValue] = ListBuffer(“ Adams”,“ Mas”)

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

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