Swift中如何将[String:Int]格式JSON解码为元组或自定义类型
适配JSON字典到自定义Skill结构的解码方案
针对你遇到的Persona5合成APP中,JSON的skills字段([String: Int])需要转成自定义结构或元组的问题,直接通过修改Codable解码逻辑就能解决,不用手动改JSON。以下是具体实现:
1. 定义自定义Skill结构体(推荐,比元组易维护)
struct PersonaSkill: Codable { let skillName: String let requiredLevel: Int }
可根据需求调整字段名,比如把skillName改成name,requiredLevel改成level
2. 修改Persona模型的Skills字段类型
把原来对应JSON字典的字段类型从[String: Int]改成[PersonaSkill]:
struct Persona: Codable { let personaName: String // 保留原有其他字段,比如属性、等级等 var skills: [PersonaSkill] }
3. 自定义解码逻辑
在Persona结构体里实现init(from decoder: Decoder),手动把JSON字典转成Skill数组:
extension Persona { enum CodingKeys: String, CodingKey { case personaName = "name" // 对应JSON里的key,根据实际JSON字段调整 case skills // 其他字段的CodingKey } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) // 解码常规字段 personaName = try container.decode(String.self, forKey: .personaName) // 解码其他原有字段,比如属性、等级等 // 核心:把[String:Int]字典转成[PersonaSkill]数组 let skillsDict = try container.decode([String: Int].self, forKey: .skills) skills = skillsDict.map { skill in PersonaSkill(skillName: skill.key, requiredLevel: skill.value) } } }
4. 可选:支持编码回原JSON格式
如果之后需要把修改后的Persona数据存回JSON,添加编码逻辑:
extension Persona { func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) // 编码常规字段 try container.encode(personaName, forKey: .personaName) // 编码其他字段 // 把[PersonaSkill]转回[String:Int]字典 let skillsDict = Dictionary(uniqueKeysWithValues: skills.map { ($0.skillName, $0.requiredLevel) }) try container.encode(skillsDict, forKey: .skills) } }
关于元组的说明
如果一定要用元组(比如[(String, Int)]),解码逻辑类似,把map的返回改成元组即可,但元组无法实现Codable自动编码/解码,后续扩展和维护远不如自定义结构体方便,不推荐。
内容的提问来源于stack exchange,提问作者kbartlett
相关产品推荐
相关产品推荐

