SwiftUI 问答之 解码 JSON (Swift) 时将单个字符串拆分为几个部分

实战需求

解码 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)
}

关于如何以一种很好的整洁方式实现这一目标的任何建议将不胜感激。我知道有很多解析字符串的方法,但我不确定如何最好地在循环中完成它。我还应该注意,解码器是通用的,因为它需要导入许多其他(更简单的)JSON,并且需要保留此功能。

解决方案

要使“代码”与您已有的内容兼容并具有组件 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])
    }
}

请注意,使用惰性变量时,您需要声明:

var code = Codes(id: "1012111000")

不是

let code = Codes(id: "1012111000")

与功能一样。


精品教程推荐


加入我们一起学习SwiftUI

QQ:3365059189
SwiftUI技术交流QQ群:518696470
教程网站:www.openswiftui.com

发表回复