将 [[[Double]]] 投射回 [Double]

jingo_man

我有一个下载的 JSON 文件。在其中,有两种类型中的一种的重复对象 - a[Double]或 a [[[Double]]]

我正在尝试将 Codable 协议用于自定义结构以将数据转储到对象中。为了解决上述问题,我实际上将更简单[Double][[[Double]]]类型转换为相同的类型。

稍后,在使用此数据时,我正在努力将其转换回更简单的单层阵列。我希望我可以强制将其强制转换回单一as! [Double]类型。我还能怎么做?我是否需要为每个阵列层设置一个“for in”循环?

或者,我如何调整我的 Geometry 结构,以便我不会为此属性使用不同类型的数组?我想知道是否coordinates可以将属性更改为 typeAny或其他类型?

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

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

谢谢

奈姆

您没有提供实际的 JSON。所以,我认为它有点像:

{
    "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

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在 JSON 中s 和您的属性struct相同,您就不需要提供CodingKeys.

现在解码:

let jsonData = """
{
    "geometries" :
    [
        {
            "coordinates" : [1.0, 2.0],
            "type" : "flat"
        },
        {
            "coordinates" : [[[111.0, 222.0]]],
            "type" : "multi"
        }
    ]
}
""".data(using: .utf8)!

do {
    let root = try JSONDecoder().decode(Root.self, from: jsonData)
    root.geometries.forEach({ (geometry) in
        geometry.coordinates.forEach({ (coordinate) in
            if case .double(let double) = coordinate {
                print(double)   // 1.0, 2.0
            }
            if case .arrayOfDoubleArray(let array) = coordinate {
                print(array)    // [[111.0, 222.0]]
            }
        })
    })
} catch {
    print(error)
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

R:将数据投射回原始格式

来自分类Dev

将double []包装为Double []

来自分类Dev

将ListBox项目投射回其Collection类型

来自分类Dev

如何“投射” HashMap<Parent, Double> 到 HashMap<Child, Double>

来自分类Dev

无法将double [] []转换为double **

来自分类Dev

将double数组绑定为double *&

来自分类Dev

错误:无法将“ <lambda(double)>”转换为“ double(*)(double)”

来自分类Dev

在java中将float除以double与将double除以double

来自分类Dev

将列表转换为Double [] []

来自分类Dev

将Byte []转换为Double

来自分类Dev

将AnyObject转换为Double

来自分类Dev

将double转换为string

来自分类Dev

将double转换为int

来自分类Dev

将Char转换为double

来自分类Dev

将NSObject转换为double

来自分类Dev

将double转换为int

来自分类Dev

将Double转换为Integer

来自分类Dev

将Double转换为Int

来自分类Dev

将 Double 的 SparseArray 写入 Parcel

来自分类Dev

将 double 转换为 BigInteger

来自分类Dev

设置Spark RDD大小:在10 ^ 9 +内将long投射为Double以进行循环,这真的是个坏主意吗?

来自分类Dev

无法将(int,double)对添加到HashMap <Integer,Double>

来自分类Dev

将Array [Array [Double]]转换为Array [Double]

来自分类Dev

将Double打印为Int-如果不是Double值

来自分类Dev

将List <double>转换为double [n,1]

来自分类Dev

如何将UnsafeMutablePointer <Double>数组转换为Double数组?

来自分类Dev

将向量<pair <double,double>写入文件的最快方法

来自分类Dev

将Scala List [List [Double]]转换为Java double [] []

来自分类Dev

将整数乘以double并将结果存储为double