如何访问存储JSON数据的自定义类型数组实现无TableView的首都答题功能
实现方案
基础错误修正
你现有代码有两个底层问题需要先修改:
- 你定义的
CountriesFinal结构体中国家名称属性是country,现有代码里写的countriess[index].name是不存在的属性,需要改为countriess[index].country - 网络请求是异步执行的,你在
viewDidLoad里调用完后台fetch之后直接执行askQuestion()时,countriess还是空数组,出题逻辑不会生效,需要把askQuestion()的调用放到网络请求成功、数据赋值完成的回调里
生成国家-首都对应数据
不需要特意做额外的结构转换,你已经拿到了存储所有CountriesFinal对象的countriess数组,直接遍历就可以生成需要的字典和全量首都数组:
// 类内全局定义两个属性 var countryCapitalMap: [String: String] = [:] var allCapitals: [String] = [] // 网络请求成功、countriess赋值后执行以下代码填充数据 countriess.forEach { item in countryCapitalMap[item.country] = item.capital allCapitals.append(item.capital) }
出题逻辑实现
封装askQuestion方法实现生成题目和选项的逻辑:
func askQuestion() { // 判空避免崩溃 guard !countriess.isEmpty, !allCapitals.isEmpty else { return } // 随机取正确题目和答案 let correctIndex = Int.random(in: 0..<countriess.count) let questionCountry = countriess[correctIndex].country let correctCapital = countriess[correctIndex].capital // 生成选项数组,先放入正确答案 var options = [correctCapital] // 补充3个不重复的错误选项 while options.count < 4 { let randomCapital = allCapitals.randomElement()! if randomCapital != correctCapital && !options.contains(randomCapital) { options.append(randomCapital) } } // 打乱选项顺序 options.shuffle() // 这里替换为你的UI赋值逻辑:把questionCountry赋值给题目标签,四个option分别赋值给四个按钮的标题即可 print("题目:\(questionCountry)的首都是什么?") print("选项:\(options)") }
调整网络请求回调逻辑
修改fetch方法里的主线程回调代码:
DispatchQueue.main.async { // 赋值数据源 countriess = decodedResponse.countries // 填充映射字典和全量首都数组 countriess.forEach { item in countryCapitalMap[item.country] = item.capital allCapitals.append(item.capital) } // 此时数据准备完成,调用出题 askQuestion() }
内容的提问来源于stack exchange,提问作者PowerPlay
相关产品推荐
相关产品推荐

