我有一个嵌套的字典和一个包含路径片段的数组。我需要在该位置更新值。
我可能正在寻找一个递归函数,而不是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
?
答案 0 :(得分:2)
请注意,var d: [String: Any] = data[first] as! [String: Any]
复制data[first]
,而不是像&
和inout
那样引用它。因此,在调用addAt(pathFrag: &pathFrag, string: string, data: &d)
时,仅更改d
。为了使此更改反映在原始data[first]
上,您必须将d
分配回data[first]
。
执行以下操作:
var dict: [String: Any] = ["channel": ["item": ["title": 1111]]]
var pathFrag = ["channel", "item", "title"]
func addAt(pathFrag: inout [String], data: inout [String: Any]) {
if let first = pathFrag.first {
if let item = data[first] {
pathFrag.remove(at: 0)
if !pathFrag.isEmpty {
var d: [String: Any] = data[first] as! [String: Any]
addAt(pathFrag: &pathFrag, data: &d)
data[first] = d
} else {
data[first] = 123
}
}
}
}
addAt(pathFrag: &pathFrag, data: &dict)
print(dict)
答案 1 :(得分:2)
这不是您要的内容,但是这里的整个前提都是不明智的。使用let m1: Box<dyn Material> = Box::new(Iron {}); // coercion happens here
let s1 = Sphere {
radius: 1.0,
material: &m1, // so that this reference is the right type
};
是恶臭的。似乎更像是Objective-C。实际上,在Objective-C中,这整个过程是一线的:
[String:Any]
好的,那只是准备数据。这是单线:
NSMutableDictionary * d1 = [[NSMutableDictionary alloc] initWithDictionary: @{ @"title" : @1111 }];
NSMutableDictionary * d2 = [[NSMutableDictionary alloc] initWithDictionary: @{ @"item" : d1 }];
NSMutableDictionary * d3 = [[NSMutableDictionary alloc] initWithDictionary: @{ @"channel" : d2 }];
但是我会质疑整个嵌套字典的概念;在我看来,您在这里遇到了错误,您需要退后一步,重新考虑数据结构。