Scala JSON4S обработки пустых полей
Это два образца данных JSON.
pattern1
{
"data_type": "stats",
"data": [
{
"id" : "123abc",
"promoted_tweet_timeline_card_engagements": [ 0 ],
"promoted_account_follow_rate": [ 0 ],
"conversion_sign_ups": [ 0 ] // <- sometime not passed this field
}
]
}
и, иногда, не пройденное поле
pattern2
{
"data_type": "stats",
"data": [
{
"id" : "123abc",
"promoted_tweet_timeline_card_engagements": [ 0 ],
"promoted_account_follow_rate": [ 0 ]
}
]
}
Я хочу преобразовать в этот класс дела.
case class Campaign(
id: String,
promoted_tweet_timeline_card_engagements: List[Any],
promoted_account_follow_rate: List[Any],
conversion_sign_ups: Option[List[Any]],
)
это основной код
for {
JObject(data) <- json \\ "data"
JField("id", JString(id)) <- data
JField("promoted_tweet_timeline_card_engagements", JArray(promoted_tweet_timeline_card_engagements)) <- data
JField("promoted_account_follow_rate", JArray(promoted_account_follow_rate)) <- data
JField("conversion_sign_ups", JArray(conversion_sign_ups)) <- data // It can not be handled correctly when field does not exists
} yield Campaign(
id = id,
promoted_tweet_timeline_card_engagements = promoted_tweet_timeline_card_engagements,
promoted_account_follow_rate = promoted_account_follow_rate,
conversion_sign_ups = Option(conversion_sign_ups)
)
conversion_sign_ups
поля не могут быть обработаны правильно, когда данные pattern2.
Я хочу справиться с этим в одном случае класса. Как я должен это делать??
2 ответа
Проблема, кажется, заключается в следующем:
JField("conversion_sign_ups", JArray(conversion_sign_ups)) <- data
Когда объект json в данных не содержит поля translation_sign_ups. окончательное сопоставление с образцом не удастся, что приведет к сбою всего совпадения по шаблону Вот обходной путь для вас.
val result = for {
JObject(data) <- json \\ "data"
JField("id", JString(id)) <- data
JField("promoted_tweet_timeline_card_engagements",
JArray(promoted_tweet_timeline_card_engagements)) <- data
JField("promoted_account_follow_rate",
JArray(promoted_account_follow_rate)) <- data
// try to get the conversion_sign_ups field value
signUpOpt = data.find(_._1 == "conversion_sign_ups").map(_._2)
} yield {
Campaign(
id = id,
promoted_tweet_timeline_card_engagements = promoted_tweet_timeline_card_engagements,
promoted_account_follow_rate = promoted_account_follow_rate,
conversion_sign_ups = signUpOpt.flatMap {
case JArray(conversion_sign_ups) => Some(conversion_sign_ups)
case _ => None
}
)
}
Вы говорите ему, чтобы он проводил кампанию, только если были выполнены все условия. Если последнего нет, то ничего не уступает. Возможно, вам следует обработать это поле отдельно:
val out = for {
JObject(data) <- json \\ "data"
JField("id", JString(id)) <- data
JField("promoted_tweet_timeline_card_engagements", JArray(promoted_tweet_timeline_card_engagements)) <- data
JField("promoted_account_follow_rate", JArray(promoted_account_follow_rate)) <- data
} yield {
val conversion_sign_ups = (json \\ "conversion_sign_ups") match {
case JArray(sign_ups) => Some(sign_ups)
case _ => None
}
Campaign(
id,
promoted_tweet_timeline_card_engagements,
promoted_account_follow_rate,
conversion_sign_ups
)
}