将 JSON 数字数组转换为 Objective-C 或 Swift 中的 CGPoints

Convert JSON array of numbers into CGPoints in Objective-C or Swift

我正在尝试将 JSON 从 API 转换为我可以在核心图形中使用的 cgpoints 数组。

JSON 看起来像:

{"date":"2017-01-05","open":119.34,"high":120.2,"low":119.1,"close":119.7,"adjusted_close":109.7062,"volume":4261070},{"date":"2017-01-06","open":118.93,"high":121.5,"low":118.52,"close":120.76,"adjusted_close":110.6777,"volume":4089186},{"date":"2017-01-09","open":120.76,"high":121.06,"low":120.33,"close":120.43,"adjusted_close":110.3754,"volume":3021844}

我对日期和关闭字段感兴趣,我想将它们转换成这种格式

 dataPoints:@[xy(val0,119.7),xy(val1,120.76),xy(val2,120.43)];

其中 val0...val3 是映射到图表 x 维度的日期,我已经定义:

 #define xy(__x,__y) [NSValue valueWithCGPoint:CGPointMake(__x,__y)]

我不拘泥于#define。这只是 CoreGraphics 现在使用的代码。如果有另一种方法可以做到这一点,一个结构或其他东西会很棒。

我知道如何使用以下方法将 JSON 解码为数组:

struct StockReport: Codable {
    let date: String
    let stockDatumOpen, high, low, close: Double
    let adjustedClose: Double
    let volume: Int

    enum CodingKeys: String, CodingKey {
        case date
        case stockDatumOpen = "open"
        case high, low, close
        case adjustedClose = "adjusted_close"
        case volume
    }
}

typealias StockData = [StockReport]

let stockData = try? newJSONDecoder().decode(StockData.self, from: jsonData)

然而,除此之外,我不确定如何创建 CGpoints 数组。

我想我可以将日期字符串转换为自 1970 年(纪元)以来的秒数,然后将它们缩放到坐标系。或者我可以使用数组的索引作为对应于每一天的整数,但这是我所得到的。 我应该遍历数组 stockData 并一个一个地创建点吗?有没有更优雅的方式?

提前感谢您的任何建议。

假设您收到一个有效的 json 字符串(您发布的字符串不是有效的 json 字符串。您可以按日期对对象进行排序(如果它们尚未排序), 枚举元素并初始化一个 CGPoint 如下:


let json = """
    [{"date":"2017-01-05",
     "open":119.34,
     "high":120.2,
     "low":119.1,
     "close":119.7,
     "adjusted_close":109.7062,
     "volume":4261070},
    {"date":"2017-01-06",
     "open":118.93,
     "high":121.5,
     "low":118.52,
     "close":120.76,
     "adjusted_close":110.6777,
     "volume":4089186},
    {"date":"2017-01-09",
     "open":120.76,
     "high":121.06,
     "low":120.33,
     "close":120.43,
     "adjusted_close":110.3754,
     "volume":3021844}]
"""

do {
    let stocks = try JSONDecoder().decode([StockReport].self, from: Data(json.utf8))
    let points = stocks.sorted{[=11=].date < .date}.enumerated().map {
        CGPoint(x: Double([=11=].offset), y: [=11=].element.close)
    }
    print(points)
} catch {
    print(error)
}

这将打印

[(0.0, 119.7), (1.0, 120.76), (2.0, 120.43)]