How to access deeply nested dictionaries in Swift

后端 未结 10 870
名媛妹妹
名媛妹妹 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 05:03

    I had the same issue, where I wanted to get boolValue nested in dictionary.

    {
      "Level1": {
        "leve2": {
          "code": 0,
          "boolValue": 1
        }
      }
    }
    

    I tried a lot of solution but those didn't worked for me as i was missing type casting. So I used following code to get the boolValue from json, where json is a nested dictionary of type [String:Any].

    let boolValue = ((json["level1"]
        as? [String: Any])?["level2"]
        as? [String: Any])?["boolValue"] as? Bool
    
    0 讨论(0)
  • 2020-11-28 05:03

    My primary use case was reading ad-hoc values from a deep dictionary. None of the answers given worked for me in my Swift 3.1 project, so I went looking and found Ole Begemann's excellent extension for Swift dictionaries, with a detailed explanation on how it works.

    I've made a Github gist with the Swift file I made for using it, and I welcome feedback.

    To use it, you can add the Keypath.swift into your project, and then you can simply use a keyPath subscript syntax on any [String:Any] dictionary as follows.

    Considering you have a JSON object like so:

    {
        "name":"John",
        "age":30,
        "cars": {
            "car1":"Ford",
            "car2":"BMW",
            "car3":"Fiat"
        }
    }
    

    stored in a dictionary var dict:[String:Any]. You could use the following syntax to get to the various depths of the object.

    if let name = data[keyPath:"name"] as? String{
        // name has "John"
    }
    if let age = data[keyPath:"age"] as? Int{
        // age has 30
    }
    if let car1 = data[keyPath:"cars.car1"] as? String{
        // car1 has "Ford"
    }
    

    Note that the extension supports writing into nested dictionaries as well, but I haven't yet used this.

    I still haven't found a way to access arrays within dictionary objects using this, but it's a start! I'm looking for a JSON Pointer implementation for Swift but haven't found one, yet.

    0 讨论(0)
  • 2020-11-28 05:06

    The Swift 4 default: subscript for Dictionaries makes makes updating values in nested Dictionaries much more concise.

    Get and Set a default value rather than dealing with optionals:

    var dict = [String : [String : String]]()
    dict["deep", default: [:]]["nested"] = "dictionary"
    
    print(dict)
    // ["deep": ["nested": "dictionary"]]
    

    https://swift.org/blog/dictionary-and-set-improvements/

    0 讨论(0)
  • 2020-11-28 05:16

    Another option: You could try calling dict.value( forKeyPath: "ladybug.spotted.red" )!


    So I just tried this with Swift 5:

    import Foundation
    
    var d = [ "ladybug" : [ "spotted" : [ "red" : 123 ] ] ] as [String:Any]
    
    (d as NSDictionary).value(forKeyPath: "ladybug.spotted.red")
    

    and it works, but this is probably the best way:

    d["ladybug"]?["spotted"]?["red"]
    
    0 讨论(0)
提交回复
热议问题