更新NSDictionary中的嵌套值

时间:2015-03-30 17:02:33

标签: swift nsmutabledictionary nsobject

我已初始化了[NSObject: AnyObject]类型的字典,因此我可以将其保存到NSUserDefaults

这是它的样子:

var allMetadata: [NSObject: AnyObject] = [
    String: [String: String]
    // Example: "project30": ["deliverablepath": "hello"]
]

我从一开始就给deliverablepath一个值,后来我想更新它。我试过这个:

allMetadata[arrayOfProjectIDs[index]]!["deliverablepath"]! = "goodbye"

但是我收到了错误

  

postfix的操作数'!'应该有可选的类型;类型是'(NSObject,   AnyObject)'

我知道updateValue(),但它似乎覆盖了第一个嵌套层中的相邻键,所以它对我不起作用。

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

使用问题可选以避免“让金字塔”

var allMetadata: [String: [String: String]] = ["a": ["b": "c"]]
allMetadata["a"]?["b"] = "z" // ok!
allMetadata["q"]?["b"] = "d" // nil

UPD: 如果你想直接投,你应该试试这个:

var allMetadata: [NSObject: AnyObject] = ["a": ["b": "c"]]
if var dict = allMetadata["a"] as? [String: String] {
    dict["b"] = "z"

    // for dict update, because it's value typed
    allMetadata["a"] = dict
}

提到,我写过“var”,而不是“let”。

答案 1 :(得分:0)

要以安全的方式执行此操作,最好在中执行此操作,如果让金字塔如下:

if let projectId = arrayOfProjectIDs[index] {
    if var project = allMetadata[projectId] as? [String:String] {
        project["deliverablePath"] = "Goodbye"
    }
}

实际上这并不太糟糕。

答案 2 :(得分:0)

我想在这里给出一个替代答案。

我理解最初的问题是关于如何处理嵌套数组和字典,但我认为值得一提的是,使用更正式的API可以更好地实现这种数据模型。

例如,怎么样:

class Project {
    var id: String
    var deliverablePath: String
    ... etc ...
}

class ProjectRepository {
    func getProjectWithId(id: String) -> Project? {
        ...
    }
}

然后你可以使用高级代码,如:

if let project = repository.getProjectWithId("") {
    project.deliverablePath = "Goodbye"
}

在下面你仍然可以使用词典和数组来实现它。