首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用codable Swift 5解码JSON数组

用codable Swift 5解码JSON数组
EN

Stack Overflow用户
提问于 2020-10-12 11:11:23
回答 2查看 541关注 0票数 0

我想在下面的链接中解码json数据

https://stats.nba.com/stats/assistleaders?LeagueID=00&PerMode=Totals&PlayerOrTeam=Team&Season=2019-20&SeasonType=Regular+Season

但是,rowSet数据是数组中一组json数组。如何设置可编码结构来解码此数据?我可以设置以下结构来解码其他数据。

代码语言:javascript
复制
import Foundation

struct leagueLeader: Codable {
    
    var resource: String
    var parameters: parameters
    
}

struct parameters: Codable {
    var LeagueID: String
    var PerMode: String
    var StatCategory: String
    var Season: String
    var SeasonType: String
}

struct resultSet: Codable {
    
    var name: String
    var headers: [String]

}
EN

回答 2

Stack Overflow用户

发布于 2020-10-12 12:18:30

困难的部分是处理应该包含多种数据类型的rowSet

代码语言:javascript
复制
{
  "rowSet": [
    [
      1,
      1610612756,
      "PHX",
      "Phoenix Suns",
      1987
    ]
  ]
}

解决方案是声明一个枚举,每个case都有一个表示可编码数据类型的关联值

代码语言:javascript
复制
enum RowSet: Codable, Equatable {
    case integer(Int)
    case string(String)

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let x = try? container.decode(Int.self) {
            self = .integer(x)
            return
        }
        if let x = try? container.decode(String.self) {
            self = .string(x)
            return
        }
        throw DecodingError.typeMismatch(RowSet.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for RowSet"))
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch self {
        case .integer(let x):
            try container.encode(x)
        case .string(let x):
            try container.encode(x)
        }
    }
}

充满了模型:

代码语言:javascript
复制
import Foundation

struct Leader: Codable, Equatable {
    let resource: String?
    let parameters: Parameters?
    let resultSets: [ResultSet]?
}

struct Parameters: Codable, Equatable {
    let leagueId, season, seasonType, perMode: String?
    let playerOrTeam: String?

    enum CodingKeys: String, CodingKey {
        case leagueId = "LeagueID"
        case season = "Season"
        case seasonType = "SeasonType"
        case perMode = "PerMode"
        case playerOrTeam = "PlayerOrTeam"
    }
}

struct ResultSet: Codable, Equatable {
    let name: String?
    let headers: [String]?
    let rowSet: [[RowSet]]?
}

enum RowSet: Codable, Equatable {
    case integer(Int)
    case string(String)

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let x = try? container.decode(Int.self) {
            self = .integer(x)
            return
        }
        if let x = try? container.decode(String.self) {
            self = .string(x)
            return
        }
        throw DecodingError.typeMismatch(RowSet.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for RowSet"))
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch self {
        case .integer(let x):
            try container.encode(x)
        case .string(let x):
            try container.encode(x)
        }
    }
}
票数 0
EN

Stack Overflow用户

发布于 2020-10-12 12:56:58

这种JSON结构非常不寻常。它是一种逗号分隔值(CSV),不能隐式解码为结构。

一种解决方案是手动解码数组

代码语言:javascript
复制
struct RowSet: Decodable {
    let rank, teamID : Int
    let teamAbbreviation, teamName : String
    let ast : Int
    
    init(from decoder: Decoder) throws {
        var arrayContainer = try decoder.unkeyedContainer()
        guard arrayContainer.count == 5 else { throw DecodingError.dataCorruptedError(in: arrayContainer, debugDescription: "The array must contain 5 items") }
        rank = try arrayContainer.decode(Int.self)
        teamID = try arrayContainer.decode(Int.self)
        teamAbbreviation = try arrayContainer.decode(String.self)
        teamName = try arrayContainer.decode(String.self)
        ast = try arrayContainer.decode(Int.self)
    }
    
}

如注释中所述,请遵循命名约定:结构、类和枚举以大写字母开头,变量、属性、函数和枚举大小写以小写字母开头。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64311232

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档