scala json4s处理空字段

时间:2015-08-31 07:57:48

标签: scala json4s

这是两个样本json数据。

模式1

{
  "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)
    )
当pattern2数据时,

conversion_sign_ups字段无法正确处理。

我想在一个案例类中处理这个问题。 我该怎么办?

2 个答案:

答案 0 :(得分:1)

问题似乎是这一行:

JField("conversion_sign_ups", JArray(conversion_sign_ups)) <- data

当数据中的json对象不包含 conversion_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
        }
    )
}

答案 1 :(得分:0)

您告诉他只有在找到所有条件后才能制作广告系列。如果不是,那么没有任何收益。您应该单独处理该特定字段:

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
    )
  }