4

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

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

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

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

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

4

5 回答 5

3

如果您想在出现任何异常时返回默认值,您可以Try使用getOrElse

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

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

于 2019-03-08T11:43:24.177 回答
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]

于 2019-03-08T12:25:16.583 回答
2

不要忘记,json 是一个对象。

所以我们可以这样检查:

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

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

json.obj.keySet
于 2020-05-05T17:23:41.947 回答
0

我不确定,但是,我在这里查看 GitHub 存储库 它似乎在第 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
}
于 2019-03-08T10:42:23.343 回答
0

liahoy 介绍

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

例如,_

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)
于 2020-04-30T15:23:17.203 回答