如何在Swift中创建嵌套字典元素?

时间:2018-06-07 09:56:46

标签: swift dictionary

我想创建一个存储它的变量:

["messageCode": API_200, "data": {
    activities =     (
                {
            action = 1;
            state = 1;
        }
    );
    messages =     (
                {
            body = hi;
            // ...
        }
    );
}, "message": ]

我所做的是:

var fullDict: Dictionary<String, AnyObject> = [:]
fullDict["messageCode"] = "API_200" as AnyObject

var data: Dictionary<String, AnyObject> = [:]
fullDict ["data"] = data as AnyObject

这种方式是否正确以及如何添加活动?

2 个答案:

答案 0 :(得分:4)

我建议你去创建一个自定义模型:

struct Model {
    var messageCode: String
    var data: MyData
    var message: String
}

struct MyData {
    let activities: [Activity]
    let messages: [Message]
}

struct Activity {
    var action: Int
    var state: Int
}

struct Message {
    var body: String
    // ...
}

因此你可以将它用作:

let data = MyData(activities: [Activity(action: 1, state: 1)], messages: [Message(body: "hi")])
let myModel = Model(messageCode: "API_200", data: data, message: "")

但是,如果您 - 由于某种原因 - 必须将其声明为字典,它可能是这样的:

let myDict: [String: Any] = [
                            "messageCode": "API_200",
                             "data": ["activities": [["action": 1, "state": 1]],
                                      "messages": [["body": "hi"]]
                                     ],
                             "message": ""
                            ]

表示myDict是一个字典包含:

  • messageCode字符串。
  • data作为嵌套字典,其中包含:
    • activities字典数组([String: Int]数组)。
    • messages字典数组([String: String]数组)。
  • message字符串。

你应该采用建模方法的一个最简单的原因是,当从myModel读取时,你所要做的就是使用点.表示法。与将其作为字典一起使用不同,您必须考虑其值,这可能是某些问题的头痛。例如,让我们说我们想要访问数据消息数组中的第一个消息体:

型号:

myModel.data.messages.first?.body

字典:

if let data = myDict["data"] as? [String: [[String: Any]]],
   let messages = data["messages"] as? [[String: String]],
   let body = messages.first?["body"] {

    print(body)
}

答案 1 :(得分:2)

因为您明确地希望它为[String:AnyObject]

var dict: [String:AnyObject] = ["messageCode":"API_200" as AnyObject,
                                "data": ["activities": [["action":1,
                                                         "state":1]],
                                         "messages": [["body":"hi"]]] as AnyObject,
                                "message": "" as AnyObject]

基本上所有根值都应该是类型as AnyObject

或者漫长的道路:

//Activities is as Array of dictionary with Int values
var activities = [[String:Int]]()
activities.append(["action": 1,
                   "state": 1])

//Messages is an Array of string
var messages = [[String:String]]()
messages.append(["body" : "hi"])

//Data is dictionary containing activities and messages
var data = [String:Any]()
data["activities"] = activities
data["messages"] = messages

//Finally your base dictionary
var dict = [String:AnyObject]()
dict["messageCode"] = "API_200" as AnyObject
dict["data"] = data as AnyObject
dict["message"] = "" as AnyObject
print(dict)

解析这个以获取你的数据将是地狱;所有类型演员和所有类型演员。

示例(让我们捕获action):

let action = ((dict["data"] as? [String:Any])?["activities"] as? [String:Int])?.first?.value

正如您所看到的,您需要在每个级别进行类型转换。这是在Swift中使用字典的问题。太多了。

当然,您可以使用像SwiftyJSON这样的第三方库将上述内容减少为:

let action = dict["data"]["activities"][0]["action"]

但是你想要一个像这样简单的依赖吗?

相反...

如果您的结构已定义,则改为创建模型;正如Ahmad F's answer所示。它将更具可读性,可维护性和灵活性。

...但是既然你问过,这就是人们用纯Dictionary元素做的事情。

相关问题