【问题标题】:scala json4s handling empty fieldsscala json4s 处理空字段
【发布时间】:2015-08-31 07:57:47
【问题描述】:

这是两个示例 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
    }
  ]
}

而且,有时没有通过字段

模式2

{
  "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数据时无法正确处理。

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

【问题讨论】:

    标签: scala json4s


    【解决方案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
            }
        )
    }
    

    【讨论】:

      【解决方案2】:

      你是在告诉他只有在所有条件都满足的情况下才会进行一场战役。如果最后一个不是,那么什么都不是收益。您可能应该单独处理该特定字段:

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

      【讨论】:

        猜你喜欢
        • 2015-02-17
        • 2017-05-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-19
        • 2016-10-14
        • 1970-01-01
        相关资源
        最近更新 更多