【问题标题】:Transferring data from json model to array将数据从 json 模型传输到数组
【发布时间】:2020-12-12 08:14:46
【问题描述】:

是否可以将int和string值都保存在一个数组中?我需要帮助。我从 JSON API 中提取数据。但我无法将一些变量转移到数组中。

我的模型是:

struct Input: Codable {
    let name: String
    let species: Species
    let gender: Gender
    let house, dateOfBirth: String
    let yearOfBirth: YearOfBirth
    let ancestry, eyeColour, hairColour: String
    let wand: Wand
    let patronus: String
    let hogwartsStudent, hogwartsStaff: Bool
    let actor: String
    let alive: Bool
    let image: String
}



enum YearOfBirth: Codable {
    case integer(Int)
    case string(String)

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let x = try? container.decode(Int.self) {
            self = .integer(x)
            return
        }
        if let x = try? container.decode(String.self) {
            self = .string(x)
            return
        }
        throw DecodingError.typeMismatch(YearOfBirth.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for YearOfBirth"))
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch self {
        case .integer(let x):
            try container.encode(x)
        case .string(let x):
            try container.encode(x)
        }
    }
}

当我将 yearOfBirth 转换为 String 或 Integer 数组时,它给出了错误无法将“YearOfBirth”类型的值转换为预期的参数类型“String”

打印 yearOfBirth :

integer(1980)
integer(1979)
integer(1980)
integer(1980)
integer(1925)
integer(1977)
string("")
integer(1960)

【问题讨论】:

  • 您需要将您的数组声明为 [YearOfBirth] 但我认为这是一个糟糕的设计。 yearOfBirth 属性应该是一个可选的 Int,它在 json 中没有给出年份 ws。
  • 您还可以将 YearOfBirth 数组映射到 Int 数组 let array: [Int] = [YearOfBirth.integer(3), YearOfBirth.integer(4), YearOfBirth.string("")].compactMap { if case .integer(let value) = $0 { return value } return nil }

标签: ios arrays json swift


【解决方案1】:

正在IntString 值保存在一个数组中。

要检索它们,假设您有 let years = [YearOfBirth]:

for year in years {
    switch year {
        case .string(let text): print(text) // You can handle texts here
        case .integer(let number): print(number) // You can handle numbers here
    }
}

此外,您可以将 all 转换为整数数组,例如:

let numbers: [Int] = years.compactMap { if case .integer(let number) = $0 { return number } else { return nil } }

【讨论】:

    【解决方案2】:

    由于yearOfBirth 的值只有Int 或空String,我建议使用包装结构而不是具有关联类型的枚举,并将值声明为可选Int

    struct YearOfBirth: Codable {
        let year : Int?
        
        init(from decoder: Decoder) throws {
            let container = try decoder.singleValueContainer()
            if let integerValue = try? container.decode(Int.self) {
                year = integerValue
            } else if let stringValue = try? container.decode(String.self) {
                year = Int(stringValue)
            } else {
                throw DecodingError.typeMismatch(YearOfBirth.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for YearOfBirth"))
            }
        }
    
        func encode(to encoder: Encoder) throws {
            var container = encoder.singleValueContainer()
            try container.encode(year)
        }
    }
    

    我会要求服务的所有者重构设计以发送一致的数据。发送一个空字符串作为 integer-nil-value 是荒谬的。

    【讨论】:

      猜你喜欢
      • 2016-01-17
      • 1970-01-01
      • 2017-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-11
      • 1970-01-01
      相关资源
      最近更新 更多