我有一个下载的JSON文件。在其中,有重复的对象是2种类型中的一种 - [Double]
或[[[Double]]]
。
我正在尝试使用Codable协议将自定义结构转储到对象中。为了解决上述问题,我实际上将更简单的[Double]
转换为相同的[[[Double]]]
类型。
稍后,当使用这些数据时,我正在努力将其转换回更简单的单层数组。我希望我可以强制将其转换回单as! [Double]
类型。我怎么能这样做?我需要一个" for in"每个数组层的循环?
或者,我如何调整我的Geometry结构,这样我就不会为这个属性搞乱不同类型的数组?我想知道coordinates
属性是否可以更改为Any
类型或其他类型?
struct Geometry: Codable {
let coordinates: [[[Double]]]
let type: String
enum CodingKeys: String, CodingKey {
case coordinates
case type
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
type = try container.decode(String.self, forKey: .type)
if type == "Point" {
let typeFromMapbox = try container.decode([Double].self, forKey: .coordinates)
coordinates = [[typeFromMapbox]]
} else { // THIS IS A POLYGON
coordinates = try container.decode([[[Double]]].self, forKey: .coordinates)
}
}
}
我只是开始&用Swift学习
感谢任何帮助,指示或见解
由于
答案 0 :(得分:2)
您没有提供实际的JSON。所以,我认为它有点像:
Content-length
根据上述结构,您的根级别数据类型为:
{
"geometries" :
[
{
"coordinates" : [1.0, 2.0],
"type" : "flat"
},
{
"coordinates" : [[[111.0, 222.0]]],
"type" : "multi"
}
]
}
然后,您的struct Root: Codable {
let geometries: [Geometry]
}
将被定义为:
Geometry
现在来了struct Geometry: Codable {
// As long as your coordinates should be at least a flat array. Multi dimensional array will be handled by `Coordinate` type
let coordinates: [Coordinate]
let type: String
}
数组。这可以是Coordinate
类型或Double
类型。所以用[[Double]]
包裹它:
enum
只要JSON中的
enum Coordinate: Codable { case double(Double) case arrayOfDoubleArray([[Double]]) init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() do { self = try .double(container.decode(Double.self)) } catch DecodingError.typeMismatch { do { self = try .arrayOfDoubleArray(container.decode([[Double]].self)) } catch DecodingError.typeMismatch { throw DecodingError.typeMismatch(Coordinate.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Coordinate type doesn't match")) } } } func encode(to encoder: Encoder) throws { var container = encoder.singleValueContainer() switch self { case .double(let double): try container.encode(double) case .arrayOfDoubleArray(let arrayOfDoubleArray): try container.encode(arrayOfDoubleArray) } } }
和key
中的属性相同,您就不需要提供struct
。
CodingKeys