繁体   English   中英

如何使用Argonaut解码键名称有意义的结构不良的JSON

[英]How to use Argonaut to decode poorly structured JSON where key name is meaningful

嗨, 文档中的Decode Person示例非常有用,如果JSON具有键和值,并且您可以使用键名称提取其值,但是如果组成键的字符串是任意的但有意义的话该怎么办。

对于Fxample,一个开放的加密货币api可以给出硬币的历史价格,并且返回的JSON的结构会有所不同,具体取决于我要问的硬币的基本货币以及我希望其定价的各种报价货币。我想要特定日期“ AUD”和“ XRP”中“ DOGE”的价格,返回的JSON看起来像

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

我无法导航至基准并获取其价格,然后获取价格并获取它们,因为JSON并非以这种方式构建,因此我需要查找“ DOGE”作为键,然后在重新编码的对象中知道会有一个“ AUD” '键和'XRP'键。 当然,根据我的查询,每个结果都会有所不同。

当然,当我基于它们创建搜索时,我会知道这些键,但是如何使用Argonaut解析此JSON? 我可以以某种方式创建一个关闭我的密钥名称的解码器吗?

感谢您的任何帮助或指导。

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

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

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

您可以通过检查源代码来查看argonaut的Json对象上可用的方法。

根据Fried Brice的回答,我确实走了解析路线,然后映射了结果Either以生成我的数据类型,请参见下面的代码片段,建议和改进。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM