【问题标题】:Dealing with optional field with lihaoyi ujson用 lihaoyi ujson 处理可选字段
【发布时间】:2019-07-30 08:37:55
【问题描述】:

我想使用 upickle library 的 ujson 从 json 文档中提取可选字符串。在某些文档中存在 json 字段,在其他文档中不存在。

当访问该字段并且该字段不存在时,我得到一个 NoSuchElementException:

val json = ujson.read(jsonString)
json("attributename").str

results in: java.util.NoSuchElementException: key not found: attributename

在ujson中处理可选json属性的惯用方式是什么?

【问题讨论】:

    标签: scala upickle


    【解决方案1】:

    如果您想在任何异常情况下返回默认值,您可以使用TrygetOrElse

    val result = Try(json("attributename").str).getOrElse("defaultValue")
    

    如果没有这样的键,结果将是attributename 键或defaultValue 字符串的值。

    【讨论】:

      【解决方案2】:

      我认为惯用的方法是有一个案例类,而不是手动反对 JSON AST。

      在您的案例类中,您可以有一个 Option[String] 字段。

      case class MyModel( attributeName: Option[String] )
      implicit val rw: ReadWriter[MyModel] = macroRW
      
      read[MyModel](jsonString)
      

      但从表面上看,你可以做到

      json.obj.value.get("attributename").map(_.str)
      

      回复Option[String]

      【讨论】:

        【解决方案3】:

        别忘了,json 是一个对象。

        所以我们可以这样检查:

        val json = ujson.read(jsonString)
        if (json.obj.get("attributename").nonEmpty) {
          json("attributename").str
          ...
        }
        

        顺便说一句,你可以像这样得到keySet:

        json.obj.keySet
        

        【讨论】:

          【解决方案4】:

          我不确定,但是,我正在查看 GitHub 存储库 here 似乎在第 62 行,从第 87 行到第 99 行,它只是调用x.obj(i)

          它不执行任何检查,只是调用它。这导致java.util.NoSuchElementException 因为试图在没有检查的情况下访问。我没有看到任何版本来获取选项,甚至没有检查这个值是否存在。

          我建议通过 Scala 上的 Try/Success/Failure 习惯用法

          val tryAttr = Try{json("attributename").str}
          tryAttr match {
            case Success(_) => doYourThing
            case Failure(t: NoSuchElementException) => DoSomethingElse
          }
          

          【讨论】:

            【解决方案5】:

            根据liahoy

            规范的方法是添加None默认值

            对于example

            import upickle.default._
            
            case class User(name: String, age: Option[Int] = None)
            implicit val userRW: ReadWriter[User] = macroRW
            read[User]("""{ "name": "Picard" }""")
            

            输出

            res0: User = User(Picard,None)
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2023-02-16
              • 2021-07-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-10-07
              相关资源
              最近更新 更多