You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift如何将扁平JSON解码为带嵌套结构的结构体对象

扁平JSON解码为嵌套结构体的最简实现方案

直接使用Swift原生Codable的自定义初始化方法实现即可,零依赖、逻辑直白易维护,是落地成本最低的方案。

实现步骤

  • 给外层Day结构体定义CodingKeys,列出JSON根层级存在的所有字段,不需要从JSON读取的id字段不用放入
  • 重写init(from decoder:)方法,从根解码容器中分别读取外层需要的date字段,以及嵌套DayData需要的三个统计字段,组装成目标嵌套结构即可

完整代码

给目标结构体加入自定义解码逻辑即可,不需要改动你定义的嵌套结构:

struct Day: Codable, Identifiable {
    var id = UUID()
    var date : String
    var dayData: [DayData]

    struct DayData: Codable {
        var personel: Int
        var plane: Int
        var drone: Int
    }

    // 对应JSON根层级的字段键
    enum CodingKeys: String, CodingKey {
        case date, personel, plane, drone
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        // 解析外层字段
        date = try container.decode(String.self, forKey: .date)
        // 从同一根容器解析嵌套结构体需要的字段,组装后放入数组
        let singleDayData = DayData(
            personel: try container.decode(Int.self, forKey: .personel),
            plane: try container.decode(Int.self, forKey: .plane),
            drone: try container.decode(Int.self, forKey: .drone)
        )
        dayData = [singleDayData]
    }
}

调用方式

和普通Codable解码完全一致,注意先把你提供的JSON示例末尾多余的逗号删掉(非法JSON格式会导致解码失败):

// 合法JSON字符串
let jsonStr = """
{
    "date": "2022-02-24T00:00:00.000Z",
    "personel": 800,
    "plane": 7,
    "drone": 6
}
"""
guard let jsonData = jsonStr.data(using: .utf8) else { return }

do {
    let dayResult = try JSONDecoder().decode(Day.self, from: jsonData)
    // 解码完成即可直接使用嵌套结构
    print(dayResult.date)
    print(dayResult.dayData.first?.drone ?? 0)
} catch {
    print("解码错误:\(error)")
}

方案优势

  • 无任何第三方依赖,基于Swift原生能力实现,不存在版本兼容问题
  • 逻辑透明,后续新增/修改字段只需要调整CodingKeys和初始化方法里的解析逻辑,维护成本极低
  • 解码性能和系统默认Codable解码完全一致,不需要先转字典做二次组装,没有额外性能损耗

内容的提问来源于stack exchange,提问作者Roman R

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 06:54:26