【问题标题】:How to use Argonaut to decode poorly structured JSON where key name is meaningful如何使用 Argonaut 解码结构不佳的 JSON,其中键名有意义
【发布时间】:2018-02-04 21:55:11
【问题描述】:

嗨,the documentation 中的 Decode Person 示例非常好,如果 JSON 具有键和值,并且您可以使用键名来提取其值,但如果构成键的字符串是任意但有意义的呢?

对于 Fxample,一个开放的加密货币 api 可以提供硬币的历史价格,并且返回的 JSON 的结构因我要求的硬币的基础货币和我希望它定价的各种报价货币而异。例如,假设我想要“AUD”和“XRP”中“DOGE”的特定日期的价格,返回的 JSON 看起来像

{"DOGE":{"AUD":0.008835,"XRP":0.004988}}

我无法导航到基础并获取其价值,然后价格并获取它们,因为 JSON 不是这样构造的,我需要寻找“DOGE”作为键,然后在重新生成的对象中知道会有“AUD”键和“XRP”键。当然,根据我的查询,每个结果都会有所不同。

当然,当我根据它们创建搜索时,我知道这些键,但我如何使用 Argonaut 来解析这个 JSON?我可以以某种方式创建一个关闭我的键名的解码吗?

感谢任何帮助或指导,谢谢。

【问题讨论】:

    标签: scala argonaut


    【解决方案1】:

    由于您不提前知道属性名称是什么,因此您无法创建编解码器并将原始 JSON 直接解码为 Scala 类。

    您想将原始 JSON 解析为通用 argonaut.Json 对象,然后您可以进行模式匹配或使用 fold 来检查内容。例如:

    val rawJson: String = ...
    val parsed: Either[String, argonaut.Json] = argonaut.Parse.parse(rawJson)
    

    您可以通过检查 source code 来查看 argonaut 的 Json 对象上可用的方法。

    【讨论】:

    • 谢谢,这确实使我朝着正确的方向前进……但是弄清楚如何使用 Either 来生成我想要的数据类型仍然很痛苦,最终到达那里可能是一个有点乱,我会把它包括在任何人评论或改进:-)
    【解决方案2】:

    根据 Fried Brice 的回答,我确实沿着解析路线走,然后映射生成的 Either 以生成我的数据类型,请参见下面的代码 sn-p,欢迎提出建议和改进。

    def parseHistoricPriceJSON(rawJson: String, fromcurrency: Currency, toCurrencies: List[Currency]): Either[String, PricedAsset] = {
    import argonaut._, Argonaut._
    import monocle.macros.syntax.lens._
    val parsed: Either[String, Json] = Parse.parse(rawJson)
    val myTocurrs = Currency("XRP") :: toCurrencies
    
    parsed.right.map(outer => {
      val cursor = outer.cursor
      val ps = for {
        toC <- myTocurrs
        prices <- cursor.downField(fromcurrency.sym)
        price <- prices.downField(toC.sym)
        thep <- price.focus.number
      } yield (toC, thep.toDouble.get)
    
      PricedAsset(fromcurrency, ps)
    })
    

    }

    case class Currency(sym: String) extends AnyVal {
      def show = sym
    }
    
    case class PricedAsset(base:Currency, quotePrices: List[(Currency,Double)])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多