Swift JSON 个全是数字名称的变量。解决办法是什么?

Swift JSON variables with all numeric names. What's the work around?

我正在提取一些需要使用 Decodable 解析的 JSON 数据到 Swift。

由于大部分数据是日期,因此我有 365 个日期条目:

"20170101": 0.17, 
"20170102": 1.0, 
"20170103": 0.68, 
"20170104": 0.61, 
"20170105": 1.03, 
"20170106": 0.48, 
"20170107": 0.52, 
"20170108": 0.51, 
"20170109": 0.28, 

当我生成相关结构以吸收数据时,我如何创建一个看起来像是数字名称的变量:

var 20170101: Double

什么是数字名称的解决方法?

变量名不能以数字开头(尽管您可以在名称后面使用数字)。它们必须以字母或下划线开头 _:

var _20170101: Double
var d20170101: Double
var d_20170101: Double

在 Swift 中(与其他语言一样)变量名称不能包含空白字符、数学符号(例如加号 (+) 或减号 (-) 运算符)或某些 Unicode 值或行和 box drawing characters。这样做的主要原因是为了确保 Swift 编译器能够理解变量名称的开始位置和结束位置。

除此之外,在命名变量时:

  • 力求清晰

  • 清晰优先于简洁

  • 根据角色命名变量、参数和关联类型

有关命名约定的更多详细信息,请查看 here

您可以将 json 字典解析为 [String:Double] 并将其转换为日期和双精度的元组数组:

let json = """
{
"20170101": 0.17,
"20170102": 1.0,
"20170103": 0.68,
"20170104": 0.61,
"20170105": 1.03,
"20170106": 0.48,
"20170107": 0.52,
"20170108": 0.51,
"20170109": 0.28
}
"""

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyyMMdd"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")  

do {
    let array: [(date: Date, double: Double)] = try JSONDecoder().decode([String:Double].self, from: Data(json.utf8))
        .compactMap({ key, value in
        guard let date = dateFormatter.date(from: key) else { return nil }
        return (date, value)
    }).sorted(by: { [=12=].date < .date })
    for (date, double) in array {
        print("Date:", dateFormatter.string(from: date), "• Value:", double)
    }
} catch {
    print(error)
}

Date: 20170101 • Value: 0.17

Date: 20170102 • Value: 1.0

Date: 20170103 • Value: 0.68

Date: 20170104 • Value: 0.61

Date: 20170105 • Value: 1.03

Date: 20170106 • Value: 0.48

Date: 20170107 • Value: 0.52

Date: 20170108 • Value: 0.51

Date: 20170109 • Value: 0.28

我现在没有时间做一个编码答案,但与此同时你可以尝试在初始化程序中将你的字典解析为 [Date:Double 并设置

decoder.dateDecodingStrategy

在你的 JSONDecoder 中。我不确定 dateDecodingStrategy 是否适用于键,但似乎值得一试。查看 this post 以获取有关如何执行 dateDecodingStrategy.

的更多详细信息

您不能使用数字作为属性名称的首字母。但有时我们必须使用您在代码中显示的数字。

该问题的解决方案是使用带有枚举的 CodingKey 协议,如下所示:

enum CodingKeys: String, CodingKey {
    case date = "20170101" // You can use "date" instead of "20170101".
}