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

Swift中如何提取含数字键的JSON数据?技术问询

解决Swift中解析数字键JSON的问题

我明白你的问题了——当JSON里的键是数字时,确实没法直接用对应名字的属性来映射,因为Swift不允许变量名以数字开头。咱们来调整一下你的Codable模型就能解决这个问题。

问题根源

看你提供的JSON结构,rankings字段实际上是一个以字符串形式数字为键的字典,而不是单个Equipe对象。比如它的结构大概是这样的:

"rankings": {
  "1": { "club": {...}, "points": "xx", ... },
  "2": { "club": {...}, "points": "xx", ... },
  ...
}

而你当前的模型把rankings声明为Equipe类型,这既不符合JSON结构,也没法处理数字键的情况。

修改后的Codable模型

我们只需要把day类里的rankings类型改成[String: Equipe](因为JSON里的键是字符串格式的数字),同时调整几个不符合Swift命名规范的类名,避免编译冲突:

class Classification: Codable {
    let channel: Channel
    let classification: [Day]
    
    init(channel: Channel, classification: [Day]) {
        self.channel = channel
        self.classification = classification
    }
}

class Channel: Codable {
    let title: String
    
    init(title: String) {
        self.title = title
    }
}

class Day: Codable {
    let day: DayDetail // 重命名原day类为DayDetail,避免和属性名冲突
    
    init(day: DayDetail) {
        self.day = day
    }
}

// 原day类重命名为DayDetail,符合Swift类名首字母大写规范
class DayDetail: Codable {
    let title: String
    let rankings: [String: Equipe] // 修改为字典类型接收数字键
    
    init(title: String, rankings: [String: Equipe]) {
        self.title = title
        self.rankings = rankings
    }
}

class Equipe: Codable {
    let club: Club
    let difference: String
    let points: String
    let points_marques: String
    let points_encaisses: String
    let nombre_matchs_joues: String
    let nombre_matchs_gagnes: String
    let nombre_matchs_nuls: String
    let nombre_matchs_perdus: String
    
    init(club: Club, difference: String, points: String, points_marques: String, points_encaisses: String, nombre_matchs_joues: String, nombre_matchs_gagnes: String, nombre_matchs_nuls: String, nombre_matchs_perdus: String) {
        self.club = club
        self.difference = difference
        self.points = points
        self.points_marques = points_marques
        self.points_encaisses = points_encaisses
        self.nombre_matchs_joues = nombre_matchs_joues
        self.nombre_matchs_gagnes = nombre_matchs_gagnes
        self.nombre_matchs_nuls = nombre_matchs_nuls
        self.nombre_matchs_perdus = nombre_matchs_perdus
    }
}

class Club: Codable {
    let name: String
    let url: Logo // 原logo类重命名为Logo,符合命名规范
    
    init(name: String, url: Logo) {
        self.name = name
        self.url = url
    }
}

class Logo: Codable {
    let url: String
    
    init(url: String) {
        self.url = url
    }
}

提取数字键对应的信息

修改模型后,你就可以通过字典的键来获取对应的数据了。比如要获取rankings中键为"1"的元素的points:

// 假设你已经完成JSON解析,得到了Classification实例
if let firstDay = classification.classification.first?.day {
    print("当前轮次标题:\(firstDay.title)")
    // 获取排名第1的队伍积分
    if let topRanking = firstDay.rankings["1"] {
        print("榜首队伍积分:\(topRanking.points)")
        print("队伍名称:\(topRanking.club.name)")
    }
}

额外优化:把字典转成排序后的数组

如果你希望按排名顺序(从1到N)遍历队伍,可以把字典转成排序后的数组:

if let firstDay = classification.classification.first?.day {
    // 按数字键排序
    let sortedRankings = firstDay.rankings.sorted {
        Int($0.key) ?? Int.max < Int($1.key) ?? Int.max
    }
    
    // 遍历排序后的队伍
    for (rankNumber, equipe) in sortedRankings {
        print("排名\(rankNumber):\(equipe.club.name),积分:\(equipe.points)")
    }
}

内容的提问来源于stack exchange,提问作者erwan bert

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:35:21