使用 scala 提取嵌套的 JSON 元素
Extract nested JSON element using scala
我在 Scala 中有以下代码。我的目标是在不知道密钥的数量和深度的情况下提取密钥的值。
import org.json4s.jackson.JsonMethods._
import org.json4s.{DefaultFormats, JField, JObject, JString, JValue}
object jsonLift {
implicit val formats = DefaultFormats
val js = parse(
"""
{
"url": "imap.yahoo.com",
"credentials": {
"username": "myusername",
"password": "mypassword"
},
"some key":{
"other key": {
"username": "hello"
}
}
}
""")
def getElem(elem: String, json:JValue) = for {
JObject(child) <- json
JField(elem, JString(value)) <- child // this does not return the expected result
// JField("username", JString(value)) <- child // this returns the expected result
} yield value
def main(args: Array[String]) {
val result = getElem("username", js)
println(result)
}
}
以上代码的结果是 List(imap.yahoo.com, myusername, mypassword, hello)
,这不是我所期望的。我的预期结果是 List(myusername, hello)
.
但是,如果我直接在方法 getElem
内更改变量 elem
,使用我感兴趣的键(作为字符串)(例如:"username")我得到预期的结果:List(myusername, hello)
是键 "username" 的所有值。
如何通过使用 JSON 键的名称作为参数调用方法 getElem
来获取预期的值列表?例如:getElem("JSON key", json)
谢谢!
将getElem
改为
def getElem(elem: String, json:JValue) = for {
JObject(child) <- json
JField(`elem`, JString(value)) <- child
} yield value
在 RHS 上 elem
周围没有反引号,您将 type JField = (String, JValue)
的第一个元素绑定到一个新名称 elem
并隐藏方法参数 elem
所以,这里的问题是当你使用:
JField(elem, JString(value)) <- child
在您的理解中,elem
的这个新定义隐藏了您传递给 getElem
方法的 elem
。
我猜你的意图是,如果传递给 getElem
的值 elem
与 JField
的名称相同,这将匹配。然而,这不是它的工作方式,相反,符号 elem 绑定到键名。
您可以通过对上面的行进行如下小改动来实现您想要的效果:
JField(key, JString(value)) <- child if key == elem
仅当 JField
的名称匹配 elem
.
时才会将值绑定到 value
我在 Scala 中有以下代码。我的目标是在不知道密钥的数量和深度的情况下提取密钥的值。
import org.json4s.jackson.JsonMethods._
import org.json4s.{DefaultFormats, JField, JObject, JString, JValue}
object jsonLift {
implicit val formats = DefaultFormats
val js = parse(
"""
{
"url": "imap.yahoo.com",
"credentials": {
"username": "myusername",
"password": "mypassword"
},
"some key":{
"other key": {
"username": "hello"
}
}
}
""")
def getElem(elem: String, json:JValue) = for {
JObject(child) <- json
JField(elem, JString(value)) <- child // this does not return the expected result
// JField("username", JString(value)) <- child // this returns the expected result
} yield value
def main(args: Array[String]) {
val result = getElem("username", js)
println(result)
}
}
以上代码的结果是 List(imap.yahoo.com, myusername, mypassword, hello)
,这不是我所期望的。我的预期结果是 List(myusername, hello)
.
但是,如果我直接在方法 getElem
内更改变量 elem
,使用我感兴趣的键(作为字符串)(例如:"username")我得到预期的结果:List(myusername, hello)
是键 "username" 的所有值。
如何通过使用 JSON 键的名称作为参数调用方法 getElem
来获取预期的值列表?例如:getElem("JSON key", json)
谢谢!
将getElem
改为
def getElem(elem: String, json:JValue) = for {
JObject(child) <- json
JField(`elem`, JString(value)) <- child
} yield value
在 RHS 上 elem
周围没有反引号,您将 type JField = (String, JValue)
的第一个元素绑定到一个新名称 elem
并隐藏方法参数 elem
所以,这里的问题是当你使用:
JField(elem, JString(value)) <- child
在您的理解中,elem
的这个新定义隐藏了您传递给 getElem
方法的 elem
。
我猜你的意图是,如果传递给 getElem
的值 elem
与 JField
的名称相同,这将匹配。然而,这不是它的工作方式,相反,符号 elem 绑定到键名。
您可以通过对上面的行进行如下小改动来实现您想要的效果:
JField(key, JString(value)) <- child if key == elem
仅当 JField
的名称匹配 elem
.
value