从JSON解析的数组中的字典中获取数据

时间:2018-03-12 16:52:41

标签: arrays json swift dictionary

我有一个带字典的数组,

(
    {
    "id_color" = 8;
    nombre = "Amarillo p\U00e1lido";
},
    {
    "id_color" = 9;
    nombre = "Amarillo p\U00e1lido/toffy claro";
},
    {
    "id_color" = 13;
    nombre = Azul;
},
    {
    "id_color" = 12;
    nombre = Magenta;
},
    {
    "id_color" = 18;
    nombre = Morado;
})

我可以访问这样做的词典数据:

let coloresArray = jsonResult["colores"] as! NSArray
            let colorDict = coloresArray[0] as! NSDictionary
            print (colorDict["nombre"]!)

但是有没有办法可以像这样访问键的值

jsonResult["colores"][0]["nombre"]

感谢您的回答

4 个答案:

答案 0 :(得分:0)

您需要正确施放步骤。解析JSON数据时,请避免强制转换和强制解包。

获取所需数据的正确而安全的方法是:

if let colores = jsonResult["colores"] as? [[String:Any]], let nombre = colores[0]["nombre"] as? String {
    print(nombre)
}

答案 1 :(得分:0)

作为一个纯粹的语法问题,你总是可以嵌套表达式,甚至包含as!运算符的表达式:

var s = ((jsonResult["colores"] as! NSArray)[0] as! NSDictionary)["nombre"] as! NSString

然而,出于多种原因,这是糟糕的风格和策略。至少,使用原生的Swift类型:

 var s = ((jsonResult["colores"] as! [Any])[0] as! [String: Any])["nombre"] as! String

但如果解包失败,这将导致崩溃,因此请使用链式选项:

 var s = ((jsonResult["colores"] as? [Any])?[0] as?[String: Any])?["nombre"] as? String // Now s is String?, be sure to treat as Optional

但你也可以一次性进行类型转换:我们想要一个带字符串键的字典数组:

var s = (jsonResult["colores"] as? [[String: Any]])?[0]["nombre"] as? String

或者,你可能想要采取其他属性,所以也许:

if let colorObj = (jsonResult["colores"] as? [[String: Any]])?[0] {
    if let s = colorObj["nombre"] as String { ... }
    if let id = colorObj["id_color"] as Int { ... }
}

然而,如果这看起来很痛苦,那是因为它是,并且您可能希望通过Codable接口利用从JSON到本机Swift对象的内置转换:

https://medium.com/xcblog/painless-json-parsing-with-swift-codable-2c0beaeb21c1

答案 2 :(得分:0)

你可以试试这个:

struct struct_color : Decodable {
        let id_color: Int
        let nombre: String
    }

    private func get_data()
    {
        let url_request = URLRequest(url: URL(string: "http://masterfood.000webhostapp.com/test/")!)
        URLSession.shared.dataTask(with: url_request)
        { (url_data, url_response, url_error) in
            if let error = url_error {
                print(error)
            } else {
                if let data = url_data {
                    do {
                        let colores = try JSONDecoder().decode([struct_color].self, from: data)
                        print("\n\n")
                        print(colores)
                        print("\n")
                        for color in colores
                        {
                            print("\(color.id_color) : \(color.nombre)")
                        }
                        print("\n\n")
                    } catch {
                        let err = error as NSError
                        print(err)
                    }
                }
            }

        }.resume()
    }




    /*


[ViewController.struct_color(id_color: 1, nombre: "amarillo"), 
         ViewController.struct_color(id_color: 2, nombre: "cafe"), 
         ViewController.struct_color(id_color: 3, nombre: "gris"), 
         ViewController.struct_color(id_color: 4, nombre: "rojo")]


1 : amarillo
2 : cafe
3 : gris
4 : rojo
*/

答案 3 :(得分:0)

我建议使用Decodable协议将JSON解码为结构,没有类型转换,没有键/索引订阅:

let jsonString = """
{"colores":[{"id_color":8,"nombre":"Amarillo pálido"},
{"id_color":9,"nombre":"Amarillo pálido/toffy claro"},
{"id_color":13,"nombre":"Azul"},
{"id_color":12,"nombre":"Magenta"},
{"id_color":18,"nombre":"Morado"}]}
"""

struct Root : Decodable {
    let colores : [Color]
}

struct Color : Decodable {
    private enum CodingKeys: String, CodingKey { case idColor = "id_color", nombre}

    let nombre : String
    let idColor : Int
}


let data = Data(jsonString.utf8)

do {
    let root = try JSONDecoder().decode(Root.self, from: data)
    for color in root.colores {
        print(color.nombre)
    }
} catch { print(error) }