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

Swift 5如何将JSON数组对象转换为仅含trialid的列表并解决相关报错

解决方案

1 基础遍历与trialid数组提取

你原代码中解码逻辑写法有误,JSONDecoder.decode第一个参数需要传入解码目标的类型,而非实例,修正后提取trialid数组的写法如下:

struct TestStructure: Decodable { // Swift类型规范首字母大写
    let name: String?
    let orderid: Int?
    let trialid: Int?
}

func fetch() {
    guard let url = URL(string: "test.com") else { return }
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.httpBody = "id=1".data(using: .utf8)
    URLSession.shared.dataTask(with: request) { data, _, error in
        guard let data = data else { return }
        do {
            // 传入数组类型作为解码目标
            let resultList = try JSONDecoder().decode([TestStructure].self, from: data)
            // 提取非空trialid,得到[Int]类型的数组,形如[27,33]
            let trialIdList = resultList.compactMap(\.trialid)
            print(trialIdList)
        } catch {
            print(error)
        }
    }.resume()
}

2 报错修复

你遇到的两个报错均由(nav.map(\.trialid)) { "\($0)" }.map这段错误写法导致:

  • 问题2报错原因:nav.map(\.trialid)得到的是[Int?]类型的数组,你后续直接追加闭包相当于尝试把数组当做函数调用,语法不成立
  • 问题1报错原因:错误的链式写法让编译器无法推断最终返回值的类型,触发类型推断失败报错

修正后的完整代码如下:

case .success(let data):
    do {
        let nav = try JSONDecoder().decode([TestStructure].self, from: data)
        // 用compactMap一次性完成nil过滤、字符串转换、控制器创建,逻辑连贯无语法问题
        self.viewControllers = nav.compactMap { item in
            // 过滤trialid为nil的项
            guard let trialId = item.trialid else { return nil }
            let idStr = "\(trialId)"
            guard let storyboard = storyboard,
                  let selectedImage = UIImage(named: "Tab4_Large"),
                  let normalImage = UIImage(named: "Tab4_Large") else {
                return nil
            }
            let controller = storyboard.instantiateViewController(withIdentifier: idStr)
            controller.view.backgroundColor = .white
            controller.floatingTabItem = FloatingTabItem(selectedImage: selectedImage, normalImage: normalImage)
            return controller
        }
    } catch {
        print(error)
    }

可选优化

如果接口返回的trialid字段一定存在,可将TestStructure中的trialid属性改为非可选类型let trialid: Int,即可省去compactMap的nil判断逻辑,直接使用map生成控制器数组即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 19:27:00