我有一些带有一些字段的json,我想检查它们中是否有一些存在。我正在提取值并针对JNothing测试它,但它太冗长了:
val json: JValue = ...
val jsonIsType1 = (json \ "field1") != JNothing && (json \ "field2") != JNothing
是否有更简洁的方法使用json4s / lift-json检查json对象中是否存在字段?理想情况如下:
val jsonIsType1 = json.has("field1") && json.has("field2")
答案 0 :(得分:18)
JValue没有'has'操作符,但Scala的implicits功能允许您添加该功能而不会有太多麻烦。
以下是一个例子:
implicit class JValueExtended(value: JValue) {
def has(childString: String): Boolean = {
if ((value \ childString) != JNothing) {
true
} else {
false
}
}
}
用法示例:
scala> val json = Json.parse("""{"field1": "ok", "field2": "not ok"}""")
scala> json.has("field1")
res10: Boolean = true
答案 1 :(得分:2)
您还可以将多个读取/验证步骤组合在一起以便理解。以下是两个函数,一个返回Option[_]
,另一个返回Boolean
。第一个允许也使用数据,而后者只进行验证。
import org.json4s.jackson.JsonMethods._
val text =
"""
|{
| "foo": "bar",
| "baz": "fnord",
| "qux": true
|}
""".stripMargin
val json = parse(text)
def readFoo(x: JValue): Option[(String, String, Boolean)] = for {
JObject(_) <- x.toOption
JString(foo) <- (x \ "foo").toOption
JString(baz) <- (x \ "baz").toOption
JBool(qux) <- (x \ "qux").toOption
if (qux == true)
} yield (foo, baz, qux)
def validateOnly(x: JValue): Boolean = (for {
JObject(_) <- x.toOption
JString(foo) <- (x \ "foo").toOption
JString(baz) <- (x \ "baz").toOption
JBool(qux) <- (x \ "qux").toOption
if (qux == true)
} yield true) getOrElse false
println(readFoo(json)) // Some((bar,fnord,true))
println(readFoo(json).isDefined) // true
println(validateOnly(json)) // true