Подтвердить что ты не робот

Синтаксический анализ Json Array в игровой структуре JsObject

У меня есть следующий 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 таким образом.

спасибо за помощь в этом.

4b9b3361

Ответ 1

Я бы сказал, что как правило, рекомендуется как можно раньше перейти от JSON-land к родному-w60 -представлению. Если obj является вашим JsObject, например, вы можете написать это:

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]

Этот последний подход делает обработку ошибок еще более чистым (например, вы можете просто заменить as на asOpt на этом верхнем уровне) и прекрасно сочетается с другими экземплярами класса Reads - если у вас есть JsArray этих объекты, например, вы можете просто написать array.as[List[Category]] и получить то, что ожидаете.

Ответ 2

Что сказал Питер, или:

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

Ответ 3

Что-то вроде этого:

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

Обычно это возвращает Option[List[String]]