Swift解码混合类型JSON数组:如何避免使用双迭代器?
优化异构JSON数组的Swift解码实现
你当前的实现使用了两个unkeyedContainer分别完成类型判断和解码操作,存在遍历冗余,还可能因容器不同步引发潜在问题。以下是更简洁高效的优化方案,仅通过一次遍历完成所有逻辑:
import Foundation struct JSONArray: Decodable { let a: [A] let b: [B] init(from decoder: Decoder) throws { var container = try decoder.unkeyedContainer() var aArray: [A] = [] var bArray: [B] = [] while !container.isAtEnd { // 通过嵌套容器判断当前元素的类型 let nestedContainer = try container.nestedContainer(keyedBy: CodingKeys.self) if nestedContainer.contains(.a) { // 直接从当前容器解码A类型元素 let item = try container.decode(A.self) aArray.append(item) } else if nestedContainer.contains(.b) { // 直接从当前容器解码B类型元素 let item = try container.decode(B.self) bArray.append(item) } else { // 可选:处理未知类型元素,避免解码失败 _ = try container.decode(UnknownElement.self) } } a = aArray b = bArray } private enum CodingKeys: String, CodingKey { case a, b } // 用于跳过未知类型元素的空结构体 private struct UnknownElement: Decodable {} } struct A: Decodable { let a: String } struct B: Decodable { let b: String } // 测试代码 let json = """ [ { "a": "abc" }, { "a": "def" }, { "b": "def" }, { "c": "ignore" } ] """ guard let data = json.data(using: .utf8) else { fatalError() } do { let decoded = try JSONDecoder().decode(JSONArray.self, from: data) print("A数组: \(decoded.a)") print("B数组: \(decoded.b)") } catch { print("解码失败: \(error)") }
核心优化点
- 单次遍历:仅用一个
unkeyedContainer完成类型判断与解码,消除冗余遍历 - 状态可靠:无需维护两个容器的同步状态,避免因容器偏移导致的解码错误
- 扩展性强:新增类型时只需在判断分支中添加对应解码逻辑,未知类型可统一跳过或抛出错误
内容的提问来源于stack exchange,提问作者Anton
相关产品推荐
相关产品推荐

