如何在Swift中给定路径片段的嵌套字典中更新值?

时间:2019-03-16 15:17:42

标签: swift dictionary inout

我有一个嵌套的字典和一个包含路径片段的数组。我需要在该位置更新值。

我可能正在寻找一个递归函数,而不是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

2 个答案:

答案 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 }];

但是我会质疑整个嵌套字典的概念;在我看来,您在这里遇到了错误,您需要退后一步,重新考虑数据结构。