Я хочу отфильтровать свой json в поле атрибутов.

JSON выглядит так:

"subject": "cars",
"price": [25],
"location":{city: "Oslo", postalcode :441},
"attributes" :
[{"key":"tc", "value":2, "key_label":typecars", "value_label":"WPD"}, 
{"key":"lk", "value":1, "key_label":"lookupcars", "valnotEqualReadsue_label":"fed"}
{"key":, "value":6, "key_label":"year", "value_label":"fzef"}
{"key":"nc", "value":3, "key_label":ncars", "value_label":"POD"}
{"key":"tc", "value":4, "key_label":plcars", "value_label":"LOD"}
{"key":"pm", "value":5, "key_label":pomcars", "value_label":"PLD"}]

Я хочу сохранить только key_label и value_label, где key_label = "year" и "pomcars". Как я могу это сделать ?

Я старался

case class Attribut(key_label: Option[String]                    
                   , value_label: Option[String]
)

case class Ads(subject: Option[String]
           , price: Option[Int]
           , location: Option[Location]
           , attribut: Option[Seq[Attribut]]

Находятся

 implicit val adsReads: Reads[Ads] = (
 (JsPath \ "subject").readNullable[String] and
 (JsPath \ "price" \ 0).readNullable[Int] and
 (JsPath \ "location").readNullable[Location] and
 (JsPath \ "attributes").readNullable[Seq[Attribut]].filter {
 case Some(Attribut(Some(key_label), _)) => (key_label == "year") || key_label == "pomcars")
 case _                                  => false
                }  
 ) (Ads.apply _)

У меня следующая ошибка: нельзя создать экземпляр конструктора ожидаемого типа; найдено: Требуется атрибут: Seq [Attribut]

Спасибо за помощь.

0
fleur 5 Окт 2020 в 12:17

1 ответ

Лучший ответ

Самый простой способ сделать это - просто прочитать JSON и обработать его, как только это будет Seq классов case.

Например, прочтите это так:

case class Attribute(key_label: Option[String], value_label: Option[String])

object Attribute {
  implicit val reads: Reads[Attribute] = Json.reads[Attribute]
}

json.as[Seq[Attribute]] // or `.asOpt` if you can't guarantee that it'll work

Затем вы можете сделать что-то вроде фильтрации значений, которые вам не нужны, или свернуть Seq, например:

json.as[Seq[Attribute]].filter {
  case Attribute(Some(key_label), _) => (key_label == "year") || (key_label == "pomcars")
  case _                             => false
}

Или же:

json.as[Seq[Attribute]].foldLeft(Seq[Attribute]()) {
  case (acc, curr@Attribute(Some(key_label), _))
    if (key_label == "year") || (key_label == "pomcars") => acc :+ curr

  case (acc, _)                                          => acc
}

Оба эти результата приводят к res0: Seq[Attribute] = List(Attribute(Some(year),Some(fzef)), Attribute(Some(pomcars),Some(PLD))).

Смотрите в прямом эфире на Scastie

1
James Whiteley 5 Окт 2020 в 12:40