【问题标题】:How to convert JSON structure into dictionary or structure如何将 JSON 结构转换为字典或结构
【发布时间】:2019-09-22 23:03:10
【问题描述】:

我正在提取不同货币的汇率。我有一个可行的解决方案,但它似乎并不优雅。我使用 JSON 输入文件,我想将其转换为字典,以便我可以轻松访问特定日期的货币汇率。

我的目标是在没有太多代码和灵活性的情况下找到最好的方法。

它在 Swift 5 中,带有一个 JSON 输入文件。输入文件如下所示:

{
"terms":{
    "url": "https://www.banqueducanada.ca/conditions-utilisation-avis/"
},
"seriesDetail":{
"FXEURCAD":{"label":"EUR/CAD","description":"Taux de change quotidien de l’euro en dollars canadiens"},
"FXGBPCAD":{"label":"GBP/CAD","description":"Taux de change quotidien de la livre sterling en dollars canadiens"},
"FXMXNCAD":{"label":"MXN/CAD","description":"Taux de change quotidien du peso mexicain en dollars canadiens"},
"FXUSDCAD":{"label":"USD/CAD","description":"Taux de change quotidien du dollar américain en dollars canadiens"}
},
"observations":[
{"d":"2019-04-29","FXUSDCAD":{"v":1.3456}, "FXEURCAD":{"v":1.5029}, "FXGBPCAD":{"v":1.7391}, "FXMXNCAD":{"v":0.07083}},
{"d":"2019-04-30","FXUSDCAD":{"v":1.3423}, "FXEURCAD":{"v":1.5055}, "FXGBPCAD":{"v":1.7493}, "FXMXNCAD":{"v":0.07071}},
{"d":"2019-05-01","FXUSDCAD":{"v":1.3416}, "FXEURCAD":{"v":1.5070}, "FXGBPCAD":{"v":1.7540}, "FXMXNCAD":{"v":0.07105}},
{"d":"2019-05-02","FXUSDCAD":{"v":1.3462}, "FXEURCAD":{"v":1.5055}, "FXGBPCAD":{"v":1.7543}, "FXMXNCAD":{"v":0.07053}},
{"d":"2019-05-03","FXUSDCAD":{"v":1.3429}, "FXEURCAD":{"v":1.5021}, "FXGBPCAD":{"v":1.7611}, "FXMXNCAD":{"v":0.07069}}
]
}

我正在提取“观察”部分。

某个日期的货币列表可能会有所不同。它可以有更多或更少。我至少有一种货币。我想要一个不需要我手动编码不同汇率的解决方案。

func getCurrencies (){
    var currencies = [String : [String:Double]]()

    if let urlJSON = URL(string: "https://www.banqueducanada.ca/valet/observations/FXUSDCAD,FXEURCAD,FXGBPCAD,FXMXNCAD/json?recent=5"){
        do {
            let contents =  try String(contentsOf: urlJSON)
            print(contents)

            let data = Data(contents.utf8)

            if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
               let observations = json["observations"] as! [[String: Any]]
                for (x,part) in observations.enumerated() {
                    let date = part["d"] as! String
                    currencies [date] = [String:Double]()

                    // get the currencies in the JSON structure

                    currencies [date]!["FXEURCAD"] = (part["FXEURCAD"] as! [String : Double])["v"]
                    currencies [date]!["FXGBPCAD"] = (part["FXGBPCAD"] as! [String : Double])["v"]
                    currencies [date]!["FXMXNCAD"] = (part["FXMXNCAD"] as! [String : Double])["v"]
                    currencies [date]!["FXUSDCAD"] = (part["FXUSDCAD"] as! [String : Double])["v"]
                } // for
                print (currencies)
            } // if  let json
        } catch {}
    } // if
} // getCurrencies

生成的currencies字典很好:

["2019-05-02": ["FXGBPCAD": 1.7543, "FXMXNCAD": 0.07053, "FXEURCAD": 1.5055, "FXUSDCAD": 1.3462], 
 "2019-05-01": ["FXGBPCAD": 1.754, "FXEURCAD": 1.507, "FXMXNCAD": 0.07105, "FXUSDCAD": 1.3416], 
 "2019-05-03": ["FXEURCAD": 1.5021, "FXUSDCAD": 1.3429, "FXMXNCAD": 0.07069, "FXGBPCAD": 1.7611], 
 "2019-04-30": ["FXEURCAD": 1.5055, "FXMXNCAD": 0.07071, "FXUSDCAD": 1.3423, "FXGBPCAD": 1.7493], 
 "2019-04-29": ["FXGBPCAD": 1.7391, "FXEURCAD": 1.5029, "FXUSDCAD": 1.3456, "FXMXNCAD": 0.07083]]

我可以使用该命令提取一个值:

   print (currencies ["2019-05-03"]!["FXUSDCAD"]!)

有没有更好的方法呢? JSONSerialization.jsonObject 是正确的做法吗?

【问题讨论】:

    标签: json swift jagged-arrays


    【解决方案1】:

    在这种情况下,JSONSerialization 是一种合理的方式,但永远不要从远程 URL 同步加载数据。

    这是一个更通用的版本,带有货币参数和异步网络请求。

    func getCurrencies(_ currencies : [String]){
        var result = [String : [String:Double]]()
    
        if let urlJSON = URL(string: "https://www.banqueducanada.ca/valet/observations/" + currencies.joined(separator:",") + "/json?recent=5"){
            URLSession.shared.dataTask(with: urlJSON) { (data, _, error) in
                if let error = error { print(error); return }
                do {
                    if let json = try JSONSerialization.jsonObject(with: data!) as? [String: Any] {
                        let observations = json["observations"] as! [[String: Any]]
                        for part in observations {
                            let date = part["d"] as! String
                            result[date] = [String:Double]()
    
                            // get the currencies in the JSON structure
                            for currency in currencies {
                                result[date]![currency] = (part[currency] as! [String : Double])["v"]
                            }
                        } // for
                        print(result)
                    } // if  let json
                } catch {
                    print(error)
                }
            }.resume()
        } // if
    } // getC
    
    
    getCurrencies(["FXUSDCAD","FXEURCAD","FXGBPCAD","FXMXNCAD"])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-18
      • 2021-12-10
      • 2013-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多