我在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)
。
但是,如果我直接在方法elem
内部使用我感兴趣的键(作为字符串)更改变量getElem
(例如:&#34;用户名&#34;)我得到了预期的结果:List(myusername, hello)
这是键的所有值&#34;用户名&#34;。
如何通过调用方法getElem
并将JSON键的名称作为参数来获取预期的值列表?例如:getElem("JSON key", json)
谢谢!
答案 0 :(得分:3)
将def getElem(elem: String, json:JValue) = for {
JObject(child) <- json
JField(`elem`, JString(value)) <- child
} yield value
更改为
elem
如果没有RHS上type JField = (String, JValue)
周围的反引号,您就会将elem
的第一个元素绑定到新名称elem
并隐藏方法参数import CoreLocation
public class SwiftLocation: NSObject, CLLocationManagerDelegate {
private let locationManager = CLLocationManager()
private var latestCoord: CLLocationCoordinate2D
init(ignore:String) {
locationManager.requestAlwaysAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.startUpdatingLocation()
latestCoord = locationManager.location!.coordinate
super.init()
locationManager.delegate = self
}
private func locationManager(manager: CLLocationManager, didUpdateToLocation newLocation: CLLocation, fromLocation oldLocation: CLLocation) {
latestCoord = manager.location!.coordinate
}
public func getLatest() -> CLLocationCoordinate2D {
return latestCoord
}
}
答案 1 :(得分:1)
所以,这里的问题是当你使用时:
JField(elem, JString(value)) <- child
在您的理解范围内,这个elem
的新定义会影响您传递到elem
方法的getElem
。
我猜你的意图是,如果传递到elem
的{{1}}值与getElem
的名称相同,那么这将匹配。但这不是它的工作原理,而是将符号elem绑定到键名。
您可以通过对上面一行的小改动来达到您想要的效果,如下所示:
JField
仅当JField(key, JString(value)) <- child if key == elem
的名称与value
匹配时才会将值绑定到JField
。