将[[[Double]]]转换回[Double]

时间:2018-03-18 22:52:29

标签: arrays swift casting codable

我有一个下载的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学习

感谢任何帮助,指示或见解

由于

1 个答案:

答案 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