How to access deeply nested dictionaries in Swift

后端 未结 10 896
名媛妹妹
名媛妹妹 2020-11-28 04:46

I have a pretty complex data structure in my app, which I need to manipulate. I am trying to keep track of how many types of bugs a player has in thier garden. There are te

10条回答
  •  抹茶落季
    2020-11-28 04:52

    If it's only about retrieval (not manipulation) then here's a Dictionary extension for Swift 3 (code ready for pasting into Xcode playground) :

    //extension
    extension Dictionary where Key: Hashable, Value: Any {
        func getValue(forKeyPath components : Array) -> Any? {
            var comps = components;
            let key = comps.remove(at: 0)
            if let k = key as? Key {
                if(comps.count == 0) {
                    return self[k]
                }
                if let v = self[k] as? Dictionary {
                    return v.getValue(forKeyPath : comps)
                }
            }
            return nil
        }
    }
    
    //read json
    let json = "{\"a\":{\"b\":\"bla\"},\"val\":10}" //
    if let parsed = try JSONSerialization.jsonObject(with: json.data(using: .utf8)!, options: JSONSerialization.ReadingOptions.mutableContainers) as? Dictionary
    {
        parsed.getValue(forKeyPath: ["a","b"]) //-> "bla"
        parsed.getValue(forKeyPath: ["val"]) //-> 10
    }
    
    //dictionary with different key types
    let test : Dictionary = ["a" : ["b" : ["c" : "bla"]], 0 : [ 1 : [ 2 : "bla"]], "four" : [ 5 : "bla"]]
    test.getValue(forKeyPath: ["a","b","c"]) //-> "bla"
    test.getValue(forKeyPath: ["a","b"]) //-> ["c": "bla"]
    test.getValue(forKeyPath: [0,1,2]) //-> "bla"
    test.getValue(forKeyPath: ["four",5]) //-> "bla"
    test.getValue(forKeyPath: ["a","b","d"]) //-> nil
    
    //dictionary with strings as keys
    let test2 = ["one" : [ "two" : "three"]]
    test2.getValue(forKeyPath: ["one","two"]) //-> "three"
    

提交回复
热议问题