解码 JSON (Swift) 时将单个字符串拆分为多个部分
Split a single string into several portions when decoding a JSON (Swift)
我有一个 JSON 文件,其中包含大约 3000 个具有以下格式(10 位数字)的唯一 ID 代码:
1012111000
我目前正在将其导入到以下格式的简单结构中:
struct Codes: Codable, Identifiable {
let id: String
}
使用以下扩展名:
extension Bundle {
func decode<T: Codable>( file: String) -> T {
guard let url = self.url(forResource: file, withExtension: nil) else {
fatalError("Failred to locate \(file) in bundle")
}
guard let data = try? Data(contentsOf: url) else {
fatalError("Failred to load \(file) from bundle")
}
let decoder = JSONDecoder()
guard let loaded = try? decoder.decode(T.self, from: data) else {
fatalError("Failed to decode \(file) from bundle")
}
return loaded
}
}
并致电
let code: [Codes] = Bundle.main.decode(file: "codes.json")
这按预期工作并且数据在 Swift.
中可用
但是
id 代码实际上由 4 个单独的代码组成。前 3 个字符是一个 3 位代码,第 4 个字符是另一个单位代码,第 5 和第 6 个字符组成第三个 2 位代码,最后 4 个字符组成最后的 4 位代码。因此,我想改为按如下方式导入到结构中:请注意,id4 是唯一的,但 id1、id2 和 id3 将重复。
struct Codes: Codable, Identifiable {
let id1: String // 1st-3rd character (3 digits)
let id2: String // 4th character (1 digit)
let id3: String // 5th-6th character (2 digits)
let id4: String // 7th-10th characters (4 digits)
}
任何有关如何以简洁的方式实现此目的的建议,我们将不胜感激。我知道有多种解析字符串的方法,但我不确定如何最好地在循环中完成此操作。我还应该注意到,解码器是通用的,因为它需要导入许多其他(更简单的)JSONs,并且需要保留此功能。
最好的,
赛
使“代码”与您已有的兼容并拥有组件 ID,
尝试这种方法,或类似的方法:
struct Codes: Codable, Identifiable {
let id: String
func id1() -> String { string(from: 0, to: 3) }
func id2() -> String { string(from: 3, to: 4) }
func id3() -> String { string(from: 5, to: 7) }
func id4() -> String { string(from: 6, to: 10) }
// or using lazy var
// lazy var id1: String = { string(from: 0, to: 3) }()
// lazy var id2: String = { string(from: 3, to: 4) }()
// lazy var id3: String = { string(from: 5, to: 7) }()
// lazy var id4: String = { string(from: 6, to: 10) }()
private func string(from: Int, to: Int) -> String {
let start = id.index(id.startIndex, offsetBy: from)
let end = id.index(id.startIndex, offsetBy: to)
return String(id[start..<end])
}
}
注意,使用lazy var时需要声明:
var code = Codes(id: "1012111000")
没有
let code = Codes(id: "1012111000")
与函数一样。
我有一个 JSON 文件,其中包含大约 3000 个具有以下格式(10 位数字)的唯一 ID 代码:
1012111000
我目前正在将其导入到以下格式的简单结构中:
struct Codes: Codable, Identifiable {
let id: String
}
使用以下扩展名:
extension Bundle {
func decode<T: Codable>( file: String) -> T {
guard let url = self.url(forResource: file, withExtension: nil) else {
fatalError("Failred to locate \(file) in bundle")
}
guard let data = try? Data(contentsOf: url) else {
fatalError("Failred to load \(file) from bundle")
}
let decoder = JSONDecoder()
guard let loaded = try? decoder.decode(T.self, from: data) else {
fatalError("Failed to decode \(file) from bundle")
}
return loaded
}
}
并致电
let code: [Codes] = Bundle.main.decode(file: "codes.json")
这按预期工作并且数据在 Swift.
中可用
但是
id 代码实际上由 4 个单独的代码组成。前 3 个字符是一个 3 位代码,第 4 个字符是另一个单位代码,第 5 和第 6 个字符组成第三个 2 位代码,最后 4 个字符组成最后的 4 位代码。因此,我想改为按如下方式导入到结构中:请注意,id4 是唯一的,但 id1、id2 和 id3 将重复。
struct Codes: Codable, Identifiable {
let id1: String // 1st-3rd character (3 digits)
let id2: String // 4th character (1 digit)
let id3: String // 5th-6th character (2 digits)
let id4: String // 7th-10th characters (4 digits)
}
任何有关如何以简洁的方式实现此目的的建议,我们将不胜感激。我知道有多种解析字符串的方法,但我不确定如何最好地在循环中完成此操作。我还应该注意到,解码器是通用的,因为它需要导入许多其他(更简单的)JSONs,并且需要保留此功能。
最好的, 赛
使“代码”与您已有的兼容并拥有组件 ID, 尝试这种方法,或类似的方法:
struct Codes: Codable, Identifiable {
let id: String
func id1() -> String { string(from: 0, to: 3) }
func id2() -> String { string(from: 3, to: 4) }
func id3() -> String { string(from: 5, to: 7) }
func id4() -> String { string(from: 6, to: 10) }
// or using lazy var
// lazy var id1: String = { string(from: 0, to: 3) }()
// lazy var id2: String = { string(from: 3, to: 4) }()
// lazy var id3: String = { string(from: 5, to: 7) }()
// lazy var id4: String = { string(from: 6, to: 10) }()
private func string(from: Int, to: Int) -> String {
let start = id.index(id.startIndex, offsetBy: from)
let end = id.index(id.startIndex, offsetBy: to)
return String(id[start..<end])
}
}
注意,使用lazy var时需要声明:
var code = Codes(id: "1012111000")
没有
let code = Codes(id: "1012111000")
与函数一样。