【问题标题】:Swift JSON response two field values append into single arraySwift JSON响应两个字段值附加到单个数组中
【发布时间】:2018-08-07 20:32:31
【问题描述】:

我正在尝试验证students == null 或可用值,如果可用值我需要将get gradestore grade 放入表数据数组中,subject null 还需要从JSON 下方存储在同一个数组For example: [10, null, 11] 中.如何在 JSON 响应的单个数组中添加这样的内容。

    {  
   "students":[  
      {  
         "id":0,
         "subject":[  
            {  
               "grade":10
            }
         ]
      },
      {  
         "id":1,
         "subject":null
      },
      {  
         "id":2,
         "subject":[  
            {  
               "grade":11
            }
         ]
      }
   ]
}

Expected output: [10,null,11,......] //This array I am going to use Tableview cell

我根据行的单元格内的nullnot null 数组值进行验证。我可以使用var array = [String?] 来接受空值,但是如何将两个不同的字段结果附加到同一个数组中?

【问题讨论】:

    标签: ios json swift


    【解决方案1】:

    您应该查看“可编码”协议。

    通过简单地定义如下结构:

    struct Student: Codable
    

    您可以将其从 JSON 解码为这些对象。

    例如:hackernoongrokswift

    【讨论】:

    • 我在没有 Struct 的情况下做了很多行代码,现在时间轴已经结束所以无法更改整个 JSON。所以请让我知道其他方式@Simon
    • 您能提供一些替代方案吗?我已经更新了我的帖子。
    【解决方案2】:

    这看起来很简单。最好的解决方案是可解码的。您从网络加载的有效负载或将被解析为结构的任何内容。现在您可以轻松地进行任何操作。

    设置:打开一个新项目。添加带有您提供的 json 有效负载的“payload.json”文件。 将以下内容添加到您的项目中。

    import UIKit
    
    struct StudentData: Decodable {
        var students: [Student]
    }
    
    struct Student: Decodable {
        var id: Int
        var subject: [Subject]?
    }
    
    struct Subject: Decodable {
        var grade: Int
    }
    
    class ViewController: UIViewController {
    
        var data: Data? {
            guard let path = Bundle(for: type(of: self)).path(forResource: "payload", ofType: "json") else { return nil }
            return try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            if let data = data {
                do {
                    let studentData = try JSONDecoder().decode(StudentData.self, from: data)
                    print(studentData)
    
                   // manipulate the structure in any way you want
    
                   let subjects: [Subject?] = studentData.students.map { $0.subject?.first }
                   print(subjects)
    
                   let nonNilValues = subjects.compactMap { $0 }
                   print(subjects)
    
                   // ... etc
    
                } catch let error {
                    print(error.localizedDescription)
                }
            }
        }
    }
    

    很抱歉没有在 Playground 中编码。太坑了。

    【讨论】:

    • 我得到输出 [Optional(test.Subject(grade: 10)), nil, Optional(test.Subject(grade: 11))] 除了 Decodable 之外还有其他方法,因为我使用的是正常的JSON解析和存储单独的数组@Oleh Zayats
    • @JUJU 我建议您了解代码中发生了什么。复制它。玩它。我的 sn-p 中的 'subjects' var 是 '[Subject?]' 类型的结构,它会在之后产生 '[Optional(Subject(grade: 10), nil, Optional(Subject(grade: 11))]'您可以从数组中提取值。
    • 当然我理解,但我使用 JSON 解析的旧方法实现了很多行,因此无法更改旧的解码模式。您能否发布如何将 '[Optional(Subject(grade: 10), nil, Optional(Subject(grade: 11))]' 提取到 [10,null,11] @Oleh Zayats
    • @JUJU 看起来是一个很好的重构机会,不是吗? :) 可编码协议使解码更容易、更安全、更易读。如果您想以旧方式解析 json,我猜您应该提供更多数据。尝试调查。通过几个步骤将您的代码移动到 Codable 并不难。如果这不是您的情况,请提供更多相关信息(当前的实现是什么)。
    • 是的,我同意我会返工,顺便说一句,我到达了最后期限,所以需要快速提交临时我需要附加两个值,如主题和主题。等级值,如 [10,null,11,。 .....] 成单表数据数组。根据该数组表单元格索引知道哪个索引值可用,哪个为空。@Oleh Zayatz
    【解决方案3】:

    试试这个

     let students = [["id": 0,"subject": [["grade": 10]]],
                        ["id": 0,"subject": nil],
                        ["id": 0,"subject": [["grade": 10]]]] as! [Dictionary<String,Any>]
    
     let array = students.map({(($0["subject"] as? [Any])?.first as? Dictionary<String,Int>)?["grade"]})
     print(array)
    

    【讨论】:

      猜你喜欢
      • 2021-05-22
      • 2022-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-16
      • 1970-01-01
      相关资源
      最近更新 更多