Swift JSON响应两个字段值附加到单个数组中

Posted

技术标签:

【中文标题】Swift JSON响应两个字段值附加到单个数组中【英文标题】:Swift JSON response two field values append into single array 【发布时间】: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?] 来接受空值,但是如何将两个不同的字段结果附加到同一个数组中?

【问题讨论】:

【参考方案1】:

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

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

struct Student: Codable

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

例如:hackernoon 或 grokswift

【讨论】:

我在没有 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)

【讨论】:

以上是关于Swift JSON响应两个字段值附加到单个数组中的主要内容,如果未能解决你的问题,请参考以下文章

Swift 根据响应类型为 JSON 字段值动态选择 Codable 结构

如何使用 Guzzle 和 Laravel 从 JSON 响应中提取单个数组值

如何保存响应 JSON 数组并在 swift 中使用用户默认值进行检索

Swift 4 可解码 - 附加变量

将值附加到数据数组并保存在 Userdefault swift

在 Swift 3 中将结构附加到结构数组上