json - 是否可以使用 Swift/Codable 解码非同质数组?
问题描述
我需要解码数组中的 JSON 数据,其中第一个元素是与以下所有对象不同的对象。我想丢弃第一个数组元素并解码其余元素。Swift Codable 可以做到这一点吗?
这是我在 Swift Playground 中整理的一个示例,它说明了正在发生的事情
import Foundation
class Test: Codable {
var name:String = ""
var number:Int = -1
}
var json1 = """
[[{"Type":"Testing", "Name":23}],
[{"name":"Rec1", "number":2}],
[{"name":"Rec2", "number":3}]]
"""
var json2 = """
[[{"name":"Rec12", "number":22}],
[{"name":"Rec22", "number":32}]]
"""
do{
let test1 = try JSONDecoder().decode([[Test]].self, from: json1.data(using: .utf8)!)
for t in test1 {
print("\(t[0].name) \(t[0].number)")
}
}catch{
print("Exception thrown 1: \(error)")
}
do{
let test2 = try JSONDecoder().decode([[Test]].self, from: json2.data(using: .utf8)!)
for t in test2 {
print("\(t[0].name) \(t[0].number)")
}
}catch{
print("Exception thrown 2: \(error)")
}
输出不足为奇。解码json1
抛出异常,解码json2
不会:
Exception thrown 1: keyNotFound(CodingKeys(stringValue: "name", intValue: nil), Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 0", intValue: 0), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "No value associated with key CodingKeys(stringValue: \"name\", intValue: nil) (\"name\").", underlyingError: nil))
Rec12 22
Rec22 32
我无法控制这些数据,我不能要求供应商做得更好——如果只是。
我能看到的唯一方法是在将 JSON 数据提供给 JSONDecoder 之前对其进行文本处理。我是 Swift 的新手,我希望有比这更好的方法......
private func _hackJSONArray(_ input:Data) throws -> Data {
/*
Input data is of the form:
[
[{"Type":"Testing", "Name":23}],
[{"name":"Rec1", "number":2}],
[{"name":"Rec2", "number":3}]
]
That is the first element is not like the others
*/
var instr = String(data:input, encoding:.utf8)!
if instr.prefix(2) != "[[" {
throw ErrorItem(theErrorType: .InvalidJSON(instr), theDescription: "Failed to decode JSON data. Did not start with: \"[[\"")
}
if let endOfFirstElement = instr.firstIndex(of: "]") {
let first = instr.index(instr.startIndex, offsetBy:1)
let last = instr.index(endOfFirstElement, offsetBy: 2)
instr.removeSubrange(first..<last)
}else{
throw ErrorItem(theErrorType: .InvalidJSON(instr), theDescription: "Failed to decode JSON data. Could not find: \"]\"")
}
return instr.data(using: .utf8)!
}
解决方案
所以,侧卫的答案是一个优雅的答案。但问题是它用不正确的数据填充了第一个数组的元素。作者说应该比被映射的更可能被扔掉。因此,在我看来,不是一个优雅但直接的解决方案是将您的数据结构字段声明为Optional
:
struct Test: Codable {
var name: String?
var number: Int?
}
然后检查你的结果是否有 nil 值:
testArray.filter({obj in
return obj.name == nil ? false : true
})
推荐阅读
- javascript - 如何在 React 中将事件处理程序作为道具传递?
- latex - 乳胶算法包错误“缺失\项目”
- javascript - 如何获取触发更改事件的引导滑块的父级
- ios - 如何使用后退按钮更新 tableviewcell?
- google-sheets - 为什么 Google 电子表格中的图片经常更换位置?
- java - 如何将声音从 raw 带到 listview 并更改它们的名称?
- c++ - 检查实现了哪些基类
- node.js - SyntaxError:块范围的声明 Ubuntu 16.04.4 LTS
- c - 将 Q18.2 转换为浮点数
- r - 使用 Shiny 中的可格式化表格手动设置条件格式边界