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

使用Swift Codable提取JSON数组中混合类型数据的方法

解决Swift中Decodable解码混合类型数组的问题

你遇到的问题我之前也碰到过——JSON数组里的元素是String和Double的混合类型,默认的Decodable没法直接处理这种情况,不过咱们通过自定义解码逻辑就能轻松搞定。

首先调整PortfolioData结构体,让它能解析每个子数组里的日期和数值。从你的示例JSON来看,每个子数组的结构是固定的:第一个元素是日期字符串,第二个是Double类型的数值,所以我们可以利用UnkeyedContainer按顺序提取对应类型的值。

修改后的完整结构体代码如下:

struct PortfolioResponseModel: Decodable {
    var dataset: Dataset
    
    struct Dataset: Decodable {
        var data: [PortfolioData]
    }
}

struct PortfolioData: Decodable {
    let date: String
    let value: Double
    
    // 自定义解码逻辑
    init(from decoder: Decoder) throws {
        // 获取无键容器,用来解析数组元素
        var unkeyedContainer = try decoder.unkeyedContainer()
        
        // 按顺序解码第一个元素为String(日期),第二个为Double(数值)
        date = try unkeyedContainer.decode(String.self)
        value = try unkeyedContainer.decode(Double.self)
    }
}

接下来你就可以正常解码并获取数据了,测试代码可以改成这样:

let myJSONArray = """
{
    "dataset": {
        "data": [
            [ "2018-01-19", 181.29 ],
            [ "2018-01-18", 179.8 ],
            [ "2018-01-17", 177.6 ],
            [ "2018-01-16", 178.39 ]
        ]
    }
}
"""

do {
    guard let jsonData = myJSONArray.data(using: .utf8) else {
        print("无法将字符串转换为Data")
        return
    }
    
    let details2 = try JSONDecoder().decode(PortfolioResponseModel.self, from: jsonData)
    
    // 获取第一个元素的日期
    if let firstPortfolioItem = details2.dataset.data.first {
        print("第一个日期:\(firstPortfolioItem.date)") // 输出 "2018-01-19"
        print("对应数值:\(firstPortfolioItem.value)") // 输出 181.29
    }
    
    // 遍历所有数据
    for item in details2.dataset.data {
        print("日期:\(item.date),数值:\(item.value)")
    }
} catch {
    print("解码失败:\(error.localizedDescription)")
}

原理说明

UnkeyedContainer是Decodable专门用来处理数组这类无键集合的容器,我们可以通过它按顺序逐个解码数组里的元素,刚好匹配JSON里子数组的固定顺序(日期在前,数值在后)。如果你的JSON偶尔会出现类型不一致的情况,还可以在解码时添加容错处理(比如用try?尝试解码,或者自定义错误类型),不过从你的示例来看,结构是规范的,上面的代码完全够用。

内容的提问来源于stack exchange,提问作者Mehul Parmar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:44:31