我一直在研究递归函数,从表示为NSDictionary的JSON数据中提取String值。该功能允许您执行此操作:
if let value = extractFromNestedDictionary(["fee" : ["fi" : ["fo" : "fum"]]], withKeys: ["fee", "fi", "fo"]) {
println("\(value) is the value after traversing fee-fi-fo");
}
功能实现如下:
// Recursively retrieves the nested dictionaries for each key in `keys`,
// until the value for the last key is retrieved, which is returned as a String?
func extractFromNestedDictionary(dictionary: NSDictionary, withKeys keys: [String]) -> String? {
if keys.isEmpty { return nil }
let head = keys[0]
if let result: AnyObject = dictionary[head] {
if keys.count == 1 {
return result as? String
} else {
let tail: [String] = Array(keys[1..<keys.count])
if let result = result as? NSDictionary {
return extractFromNestedDictionary(result, withKeys: tail)
} else {
return nil
}
}
} else {
return nil
}
}
是否有一些与Swift 1.2 / 2.x中的可选绑定相关的语法功能可以:
if
嵌套答案 0 :(得分:3)
您可以在reduce
数组上使用keys
,而不是递归
遍历字典:
func extractFromNestedDictionary(dictionary: NSDictionary, withKeys keys: [String]) -> String? {
return reduce(keys, dictionary as AnyObject?) {
($0 as? NSDictionary)?[$1]
} as? String
}
在闭包内,$0
是当前级别的{可选]对象$1
当前的关键。闭包返回下一级别的对象
如果$0
是字典且具有当前密钥的值,
否则nil
。那么reduce()
的返回值就是
最后一级的对象或nil
。
答案 1 :(得分:1)
我原本不想在没有你先尝试的情况下做到这一点,但我仍然这样做,因为我喜欢Swift而且玩得很开心:
func extractFromNestedDictionary(dictionary: [NSObject : AnyObject], var withKeys keys: [String]) -> String? {
if let head = keys.first, result = dictionary[head] {
if keys.count == 1 {
return result as? String
} else if let result = result as? [NSObject : AnyObject] {
keys.removeAtIndex(0)
return extractFromNestedDictionary(result, withKeys: keys)
}
}
return nil
}
extractFromNestedDictionary(["A" : ["B" : ["C" : "D"]]], withKeys: ["A", "B", "C"])
一些注意事项:
NSDictionary
并使用[NSObject : AnyObject]
,这可以桥接到NSDictionary,而且更加快捷答案 2 :(得分:1)
我知道这并不是严格回答这个问题。但你可以使用valueForKeypath
:
let fum = dict.valueForKeyPath("fee.fi.fo")
答案 3 :(得分:0)
这是我提出的最好的......
func extractFromNestedDictionary(dictionary: [NSObject : AnyObject], withKeys keys: [String]) -> String? {
if let head = keys.first,
result = dictionary[head] as? String
where keys.count == 1 {
return result
} else if let head = keys.first,
result = dictionary[head] as? [NSObject : AnyObject] {
return extractFromNestedDictionary(result, withKeys: Array(keys[1..<keys.count]))
}
return nil
}