How to access deeply nested dictionaries in Swift

后端 未结 10 900
名媛妹妹
名媛妹妹 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:56

    Unfortunately none of these methods worked for me, so I built my own to use a simple string path like "element0.element1.element256.element1", etc. Hope this save a time for others. (just use a dots between name of elements in string)

    Json example:

    {
        "control": {
            "type": "Button",
            "name": "Save",
            "ui": {
                "scale": 0.5,
                "padding": {
                    "top": 24,
                    "bottom": 32
                }
            }
        }
    }
    

    Step 1, convert json String to Dictionary

    static func convertToDictionary(text: String) -> [String: Any]? {
            if let data = text.data(using: .utf8) {
                do {
                    return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
                } catch {
                    print(error.localizedDescription)
                }
            }
            return nil
        }
    

    Step 2, helper to get a nested objects

    //path example: "control.ui.scale"
        static func getDictValue(dict:[String: Any], path:String)->Any?{
            let arr = path.components(separatedBy: ".")
            if(arr.count == 1){
                return dict[String(arr[0])]
            }
            else if (arr.count > 1){
                let p = arr[1...arr.count-1].joined(separator: ".")
                let d = dict[String(arr[0])] as? [String: Any]
                if (d != nil){
                    return getDictValue(dict:d!, path:p)
                }
            }
            return nil
        }
    

    Step 3, use helper

    let controlScale = getDictValue(dict:dict, path: "control.ui.scale") as! Double?
    print(controlScale)
    
    let controlName = getDictValue(dict:dict, path: "control.name") as! String?
    print(controlName)
    

    Returns

    0.5
    Save
    

提交回复
热议问题