web-dev-qa-db-ja.com

プレイフレームワークJsObjectでのJson配列の解析

私は次のJsonを持っています:

{
  "web-category" : "macaroons",
  "sub-categories" : [
     { "name" : "pink" },
     { "name" : "blue" },
     { "name" : "green" }
  ]

}

PlayでJsObjectとして持っています。だから私は今、次のことを正常に行うことができます:

//(o is the JsObject)

val webCat:Option[String] = (o \ "web-category").asOpt[String]

println(webCat.toString)

>> Some(macaroons)

ここまでは順調ですね。しかし、配列Jsonオブジェクトにアクセスするにはどうすればよいですか?私はこれを持っています...

val subCats:Option[JsArray] = (o \ "sub-categories").asOpt[JsArray]

println(subCats.toString)

>> Some([{"name" : "blue"},{"name" : "green"},{"name" : "pink"}])

しかし、私が必要なのは、JsArrayを取得して、次のようなすべての名前のリストを取得することです。

List("blue", "green", "pink")

このようにJsArrayにアクセスする方法がわかりません。

これにご協力いただきありがとうございます。

34
Zuriar

一般に、できるだけ早くJSONランドからネイティブのスカラ表現ランドに移行することをお勧めします。たとえば、objJsObjectである場合、次のように記述できます。

val subCategories = (obj \ "sub-categories").as[List[Map[String, String]]]

val names = subCategories.map(_("name"))

あるいは:

case class Category(name: String, subs: List[String])

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

implicit val categoryReader = (
  (__ \ "web-category").read[String] and
  (__ \ "sub-categories").read[List[Map[String, String]]].map(_.map(_("name")))
)(Category)

その後:

obj.as[Category]

この後者のアプローチにより、エラー処理がさらにきれいになり(たとえば、このトップレベルでasasOptに置き換えることができます)、他のReads型クラスインスタンスとうまく合成できます。これらのオブジェクトのJsArray。たとえば、array.as[List[Category]]そして、あなたが期待するものを取得します。

32
Travis Brown

ピーターが言ったこと、または:

(o \ "sub-categories" \\ "name").map(_.as[String]).toList
10
johanandren

このようなもの:

subCats.map( jsarray => jsarray.value.map(jsvalue => (jsvalue \ "name").as[String]).toList)

これは通常Option[List[String]]を返します

4
Peter