【问题标题】:How can I get the data I need out of this array of arrays?如何从这个数组中获取我需要的数据?
【发布时间】:2018-09-02 21:43:29
【问题描述】:

我需要从 API 解析 JSON 以获取两个数据数组,一个用于 Times,一个用于 Price。

这是请求:

func getReq(arr: Bool, completion: @escaping (Bool) -> ()){
    Dates.shared.formatDate()

    switch graphSetup {
    case .day:
        days = "1"
    case .week:
        days = "14"
    }

    let url = "https://api.coingecko.com/api/v3/coins/bitcoin/market_chart?vs_currency=usd&days=1"

    Alamofire.request(url).responseJSON { response in
        switch response.result {
        case .failure(let error):
            // Do whatever here
            return

        case .success(let data):
            // First make sure you got back a dictionary if that's what you expect
            let responseJSON = JSON(response.result.value!)
            if responseJSON.count != 0 {

                //do whatever you want with your object json

                parse(json: responseJSON)
                print(responseJSON)
                let gd = responseJSON["prices"].arrayValue

                completion(arr)
            }
        }
    }

这正是 JSON 返回的内容(print(responseJSON) 我缩短了它。

let json = "{
  "prices" : [
[
  1535841336422,
  7186.4600704446984
],
[
  1535841628453,
  7187.2085293179398
],
[
  1535841936398,
  7189.7057414152769
],
... many others ...,
[
  1535889024161,
  7210.4807839639352
],
[
  1535889339150,
  7211.0670314913395
 ]
]
}"

解析后,我得到了这个数组数组。如何将时间与价格分开,同时保持正确的顺序,以便创建以 [Times] 为 x 轴、[Prices] 为 y 轴的图表?

我在想这样的事情:

var times: [Int] = [] // Will probably convert to traditional date for chart
var prices: [Double] = []

所以我最终得到:

print(times)
[1535837138223,1535837424517,1535837741575,...]
print(prices)
[5560.902754859002,5542.734892949798,5539.4334214537,...]

现在可以正确设置我的图表了。我怎样才能做到这一点?或者,如果有更好的方法来设置我的图表数据,(我正在使用 danielgindi/Charts for iOS)请告诉我。

【问题讨论】:

  • 显示你的服务器返回的json
  • @LeoDabus 对不起,问题中的第一部分代码是从服务器返回的内容。我将编辑并完整添加它返回的任何其他详细信息
  • @LeoDabus 编辑为打印响应时控制台显示的内容。如果有人可以给出拒绝投票的原因,以便我改进,谢谢。

标签: ios arrays json swift charts


【解决方案1】:

您需要结构化数据并创建自定义编码器/解码器来编码/解码不同数据类型 UInt64(Unix 时代)和 Double(价格)的数组:

struct Root: Codable {
    let prices: [Price]
}
struct Price: Codable {
    let date: Date
    let price: Double
}

extension Price {
    public init(from decoder: Decoder) throws {
        var unkeyedContainer = try decoder.unkeyedContainer()
        let date = try unkeyedContainer.decode(UInt64.self).date
        let price = try unkeyedContainer.decode(Double.self)
        self.init(date: date, price: price)
    }
    public func encode(to encoder: Encoder) throws {
        var unkeyedContainer = encoder.unkeyedContainer()
        try unkeyedContainer.encode(date.unixEpochTime)
        try unkeyedContainer.encode(price)
    }
}

extension UInt64 {
    var date: Date {
        return Date(timeIntervalSince1970: TimeInterval(self)/1000)
    }
}
extension Date {
    var unixEpochTime: UInt64 {
        return UInt64(timeIntervalSince1970*1000)
    }
}

游乐场测试:

let json = """
{"prices": [[1535837138223,5560.902754859002],
            [1535837424517,5542.734892949798],
            [1535837741575,5539.4334214537]]}
"""

do {
    let prices = try JSONDecoder().decode(Root.self, from: Data(json.utf8)).prices
    print(prices.first!.date.description(with:.current))  // "Saturday, September 1, 2018 at 6:25:38 PM Brasilia Standard Time\n"
    print(prices.first!.price)  // "5560.902754859\n"

} catch {
    print(error)
}

【讨论】:

  • 非常有帮助,谢谢。我想我明白发生了什么,只是为了清楚这里试试 JSONDecoder().decode(Root.self, from: Data(json.utf8)),我会把我的 responseJSON 像:试试 JSONDecoder().decode(Root .self,来自:Data(responseJSON.utf8)) 正确吗?我会在早上试一试,然后告诉你。
  • 只需将 Data(json.utf8) 替换为成功案例中 alamofire 请求中的数据响应 response.data
  • 完美运行,我现在正试图弄清楚如何获取所有值并添加到新数组中,因为我只能单独访问它们。例如,我将如何打印价格结构中的所有价格,或者在价格中附加一个包含所有值的数组。价格,因为我只能访问价格。第一!。价格或价格。最后!。价格。
  • 我明白了,'for element in prices { print(element.price) }'
猜你喜欢
  • 2011-07-28
  • 2021-03-01
  • 1970-01-01
  • 2023-02-22
  • 1970-01-01
  • 2013-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多