【发布时间】:2019-03-16 15:17:42
【问题描述】:
我有一个嵌套字典和一个包含路径片段的数组。我需要更新那个位置的值。
我可能正在寻找递归函数,而不是 Dictionary 类型等的扩展。
我无法递归执行此操作,因为我复制了 inout 参数。
var dict: [String: Any] = ["channel": ["item": ["title": 1111]]]
var pathFrag = ["channel", "item", "title"]
var val = 123
func addAt(pathFrag: inout [String], val: Int, data: inout [String: Any]) {
if let first = pathFrag.first {
if let item = data[first] {
print(item)
pathFrag.remove(at: 0)
if !pathFrag.isEmpty {
var d: [String: Any] = data[first] as! [String: Any]
print("e: \(d)")
return addAt(pathFrag: &pathFrag, string: string, data: &d)
} else {
data[first] = val
print("else: \(data)") // ["title": 123]
}
}
}
}
addAt(pathFrag: &pathFrag, val: val, data: &dict)
print(dict)
如何将title的值更新为123?
【问题讨论】:
-
最好不要使用inout。现在您可以在返回最终值的辅助函数中进行递归。
-
当字典很大并且复制会影响性能时,我有点担心。
-
明白,但你不能一边吃蛋糕一边吃。如果你想要这种递归算法,在我看来,放弃值类型的优势,让你可以清楚地推理并只编写你想要的算法,这似乎是愚蠢的。过早的优化总是,呃,过早的。
-
另外我要指出的是,这整个概念是 unSwifty 的。使用 Any 是一种难闻的气味。在 Objective-C 中,由于 KVC 和 keypaths,这将是单行的。
-
@matt 如何使用 Objective-C 来做到这一点?我试过
var d = dict as NSDictionary; d.setValue(123, forKeyPath: "channel.item.title");,但它给了SIGABRT。
标签: swift dictionary inout