Анализ неизвестного количества элементов в SWIFT / SWIFT UI - PullRequest
0 голосов
/ 11 июля 2020

Я работаю над проектом в SwiftUI, и я новичок в синтаксическом анализе JSON.

У меня есть следующий JSON файл:

{
    "index": "001",
    "name": "Joe",
    "courses": {
        "course_1": "English",
        "course_2": "CS",
        "course_3": "Maths"
    },
    "count": 3
}

Моя проблема в том, что не каждый у студента такое же количество курсов. Как я мог получить курсы, не зная, сколько их?

Моя структура:

struct Student: Decodable {
    
    var index: String
    var name: String
    var courses: [Course]
    var count: Int
    
    struct Course {
     
  
    }
    
}

Ответы [ 2 ]

1 голос
/ 11 июля 2020

Вы также можете смоделировать struct Student так,

struct Student: Decodable {
    var index: String
    var name: String
    var courses: [String:String]
    var count: Int
}

В приведенном выше коде я использовал тип [String:String] для courses вместо [Course].

0 голосов
/ 11 июля 2020

Вы можете выполнить произвольное декодирование:

struct Student : Decodable {
    let index: String
    let name: String
    let courses: [String]
    
    enum CodingKeys: CodingKey {
        case index
        case name
        case count
        case courses
    }
    
    struct CourseCodingKeys: CodingKey {
        var stringValue: String
        
        init?(stringValue: String) {
            self.stringValue = stringValue
        }
        
        var intValue: Int?
        
        init?(intValue: Int) {
            // this creates a key such s "course_1" using an integer
            self.stringValue = "course_\(intValue)"
        }
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        // decode the simple properties
        index = try container.decode(String.self, forKey: .index)
        name = try container.decode(String.self, forKey: .name)

        // get the count
        let courseCount = try container.decode(Int.self, forKey: .count)

        // get the object that has the courses
        let nestedContainer = try container.nestedContainer(keyedBy: CourseCodingKeys.self, forKey: .courses)

        if courseCount == 0 {
            courses = []
        } else {
            // for 1 to courseCount, decode a string for that key
            courses = try (1...courseCount)
                .map { try nestedContainer.decode(String.self, forKey: CourseCodingKeys.init(intValue: $0)!) }
        }
    }
}

Использование:

// ["English", "CS", "Maths"]
try jsonDecoder.decode(Student.self, from: data).courses
...