从可选对象(字典数组)中获取值?

Posted

技术标签:

【中文标题】从可选对象(字典数组)中获取值?【英文标题】:getting values from optional object (Array of dictionary)? 【发布时间】:2018-05-23 20:15:59 【问题描述】:

我一直在尝试使用

从响应中获取“名称”
if let data = text.data(using: .utf8) 
    do 

        return try JSONSerialization.jsonObject(with: data, options: [])  as? [String : AnyObject]
     catch 
        print(error.localizedDescription)
    

return nil


for field in dict?["report_data"]?["name"] as? [Any] ?? [] 
    print(field)                   

没有成功。

回应是

Optional("content": "", "subject": "每周出席 2018-05-14 - 2018-05-20", "attachments": "[]", "report_data": "[\ "名称\":\"总天数\",\"值\":\"7\",\"名称\":\"现在天数\",\"值\":\"0\" ,\"name\":\"Total Hours\",\"value\":\".0\",\"name\":\"Average Hours\",\"value\": \".0\",\"name\":\"开始日期\",\"值\":\"2018-05-14\",\"name\":\"结束日期\",\"value\":\"2018-05-20\"]", "asset_reference": "[]", "activity_reference": "[]", "form_approval_field_reference": "[]")

请帮我解决这个问题。

【问题讨论】:

你从哪里得到text 避免可选使用 (!),if let 或 guard 语句 【参考方案1】:

实际上,您得到的响应是[String : [[String : String]]] 类型的字典。所以"report_data"键的value[[String : String]]类型的数组。

现在[[String : String]] 实际上是一个字典数组。因此,数组的每个元素都是一个字典,即 [String : String],您的 "name" 键所在的位置。

let responseDictionary: [String : Any] = [ "report_data" : [
    ["name":"Total Days","value":"7"],
    ["name":"Present Days","value":"0"],
    ["name":"Total Hours","value":".0"],
    ["name":"Average Hours","value":".0"],
    ["name":"Start Date","value":"2018-05-14"],
    ["name":"End Date","value":"2018-05-20"]
] ]

if let arrayOfDictionary = responseDictionary["report_data"] as? [[String : String]] 
    for dictionary in arrayOfDictionary 
        if let name = dictionary["name"] 
            print(name)
        
    

好吧,for dictionary in arrayOfDictionary 给了你错误,因为当你得到它时,你的回复实际上是 [String : Any] 类型。但是当值是Any 类型时,您不能执行太多操作。因此,您需要将 Any 转换为显式类型才能拥有具体对象。您需要先将 Any 类型数组转换为实际的 [[String : String]] 类型数组。



编辑: 您注定要使用格式错误的 JSON。这就是你遇到麻烦的原因。下面一起来看看DictionaryJSON的处理方法:

let responseDictionary: [String : Any] = [ "content": "",
                                       "subject": "Weekly Attendance 2018-05-14 - 2018-05-20",
                                       "attachments": "[]",
                                       "report_data" : [
                                            ["name":"Total Days","value":"7"],
                                            ["name":"Present Days","value":"0"],
                                            ["name":"Total Hours","value":".0"],
                                            ["name":"Average Hours","value":".0"],
                                            ["name":"Start Date","value":"2018-05-14"],
                                            ["name":"End Date","value":"2018-05-20"]
                                        ],
                                       "asset_reference": "[]",
                                       "activity_reference": "[]",
                                       "form_approval_field_reference": "[]"
                                    ]

您可能已将此字典转换为 JSON,然后转换为 JSON 字符串。但在此过程中,您丢失了 JSON 标准格式。这应该怎么做:

var text: String = ""

do 
    let jsonData = try JSONSerialization.data(withJSONObject: responseDictionary, options: .prettyPrinted)
    text = String(data: jsonData, encoding: .utf8) ?? ""
 catch 
    print(error.localizedDescription)

现在,如果您的 text 是一个有效的 JSON 字符串,那么您就可以开始了:

if let data = text.data(using: .utf8) 
    do 
        let response = try JSONSerialization.jsonObject(with: data, options: []) as? [String : Any]
        if let response = response, let arrayOfDictionary = response["report_data"] as? [[String : String]] 
            for dictionary in arrayOfDictionary 
                if let name = dictionary["name"] 
                    print(name)
                
            
        
     catch 
        print(error.localizedDescription)
    

【讨论】:

这是我从服务器得到的响应......它是字典数组吗?......以及为什么它是可选的......我是新手 对于数组中的字典,这一行说 Anyobject 不确认协议“序列” 如果让 arrayOfDictionary = dict!["report_data"] as? [[String : String]] ..它不会进入这个如果条件......请帮助我 已编辑。它不是作为字典数组出现的。它像字符串一样打印 您是否对收到的响应进行了 JSON 反序列化?如果没有,请发布您要检索数据的整个上下文【参考方案2】:
func dataToJSON(data: Data) -> AnyObject? 

    do         
        return try JSONSerialization.jsonObject(with: data, options: []) as AnyObject
    
    catch let myJSONError 

        print(myJSONError)
    
    return nil


if let list = self.dataToJSON(data: data) as? [Any] 

      // here is array


if let list = self.dataToJSON(data: data) as? [String: Any] 

      // here is dictionary

【讨论】:

以上是关于从可选对象(字典数组)中获取值?的主要内容,如果未能解决你的问题,请参考以下文章

不使用循环从可迭代对象中获取值

iOS:如何从一个字典内的数组内的对象中获取值?

在 swift 4.0 中从 firebase 快照字典中获取值时打开一个可选的 nil

从可选子查询中插入多个返回值

如果之前有任何为空,则从可选的有序文本框中移动值

当其他可观察对象为真时,从可观察对象中获取项目