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

如何在Swift中解码pandas DataFrame导出的split格式JSON数据

解决方法

核心思路

你之前的解码逻辑错误在于:pandas split格式的data字段存储的是按行排列的数组集合,并不是Product结构体的键值对结构,所以无法直接声明为[[Product]]类型解码。
要避免硬编码列顺序,只需要先从返回的columns字段中提前映射每个Product属性对应的列索引,再逐行读取构造对象即可。

具体实现步骤

1. 定义基础工具类型

首先实现一个可兼容Int、String等基础JSON类型的通用解码类型AnyCodable,用于解析data字段中混合类型的数组元素:

struct AnyCodable: Codable {
    let value: Any
    
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let intVal = try? container.decode(Int.self) {
            value = intVal
        } else if let stringVal = try? container.decode(String.self) {
            value = stringVal
        } else {
            throw DecodingError.dataCorruptedError(in: container, debugDescription: "不支持的类型")
        }
    }
}

2. 定义pandas split格式中间解码结构

用于先把外层的列信息和原始数据解析出来:

struct PandasSplitRawResponse: Codable {
    let columns: [String]
    let data: [[AnyCodable]]
    // index字段用不到可以直接忽略
    enum CodingKeys: String, CodingKey {
        case columns, data
    }
}

3. 实现解码转换逻辑

解码完成后先构建字段到索引的映射,再逐行构造Product数组:

func decodeProductFromPandasJSON(data: Data) throws -> [Product] {
    // 先解码原始split结构
    let rawResponse = try JSONDecoder().decode(PandasSplitRawResponse.self, from: data)
    // 提前映射每个Product属性对应的列索引,避免硬编码顺序
    guard let cprcodeIdx = rawResponse.columns.firstIndex(of: "cprcode"),
          let iprcodeIdx = rawResponse.columns.firstIndex(of: "iprcode"),
          let psqtyIdx = rawResponse.columns.firstIndex(of: "psqty") else {
        throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: [], debugDescription: "缺少必要的列字段"))
    }
    // 逐行构造Product对象
    var products = [Product]()
    for row in rawResponse.data {
        guard let cprcode = row[cprcodeIdx].value as? Int,
              let iprcode = row[iprcodeIdx].value as? String,
              let psqty = row[psqtyIdx].value as? Int else {
            throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: [], debugDescription: "行数据类型不匹配"))
        }
        products.append(Product(cprcode: cprcode, iprcode: iprcode, psqty: psqty))
    }
    return products
}

调用示例

直接传入接口返回的JSON数据即可得到[Product]结果:

// jsonData是从接口获取到的JSON数据
do {
    let products = try decodeProductFromPandasJSON(data: jsonData)
    print(products) // 得到最终需要的Product数组
} catch {
    print("解码失败: \(error)")
}

内容的提问来源于stack exchange,提问作者Nic Wanavit

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 16:15:03