我有一个简单的数组
Array[4][
"A",
1,
"A1",
13
]
但是当它包含int和string时,我如何解析JSON数组?我没有问题将内部的所有值转换为字符串,如果它们还没有,但我找不到任何函数来执行此操作。
谢谢。
Codable
复杂的方式
用unkeyedContainer
解码数组
使用条件为while
的!isAtEnd
循环并在Int
块中解码do - catch
。如果它失败解码String
JSONSerialization
轻松的方式
将对象反序列化为[CustomStringConvertible]
并使用[String]
将数组映射到"\($0)"
编辑:
这是一个如何使用Decodable
解码数组的示例,如果项是对并且类型顺序相同:
let jsonArray = """
["A", 1, "A1", 13]
"""
struct Item : Decodable {
var array = [String]()
init(from decoder: Decoder) throws {
var arrayContainer = try decoder.unkeyedContainer()
while !arrayContainer.isAtEnd {
let string = try arrayContainer.decode(String.self)
let int = try arrayContainer.decode(Int.self)
array.append(String(int))
array.append(string)
}
}
}
let data = Data(jsonArray.utf8)
do {
let result = try JSONDecoder().decode(Item.self, from: data)
print(result.array)
} catch { print(error) }
将JSON样本[1, "1"]
粘贴到quicktype中会给出以下Codable
实现:
typealias IntOrStrings = [IntOrString]
enum IntOrString: 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(IntOrString.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for IntOrString"))
}
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)
}
}
}
Here is the full source允许您执行以下操作:
let items = try IntStrings("[1, \"1\"]")
// Now you have:
// items == [.integer(1), .string("1")]
// so you can map or iterate over this
这是从JSON表示int-or-string数组的最类型安全的方法。
你得到的Array
元素为String
或Int
,类似于enum
类型的数组。所以你可以在Type
的帮助下解析底层的enum
。
将基础类型构造为:
enum StringOrIntType: Codable {
case string(String)
case int(Int)
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
do {
self = try .string(container.decode(String.self))
} catch DecodingError.typeMismatch {
do {
self = try .int(container.decode(Int.self))
} catch DecodingError.typeMismatch {
throw DecodingError.typeMismatch(StringOrIntType.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Encoded payload not of an expected type"))
}
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .int(let int):
try container.encode(int)
case .string(let string):
try container.encode(string)
}
}
}
解码过程:
let jsonData = """
["A", 1, "A1", 13, 15, 2, "B"]
""".data(using: .utf8)!
do {
let decodedArray = try JSONDecoder().decode([StringOrIntType].self, from:jsonData)
// Here, you have your Array
print(decodedArray) // [.string("A"), .int(1), .string("A1"), .int(13), .int(15), .int(2), .string("B")]
// If you want to get elements from this Array, you might do something like below
decodedArray.forEach({ (value) in
if case .string(let integer) = value {
print(integer) // "A", "A1", "B"
}
if case .int(let int) = value {
print(int) // 1, 13, 15, 2
}
})
} catch {
print(error)
}
从对已接受答案的评论:您不再需要担心物品的订购。