You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中如何对JSON字典的日期键排序以绘制时间序列图?

解决字典日期键排序问题,绘制正确的时间序列图

我完全懂你的困扰——字典本身确实是无序的,但要画时间序列图,必须把日期键按时间顺序规整好。之前的方法没生效,大概率是没把字典转换成可排序的数组,或者日期处理环节出了小问题,下面给你具体的解决方案:

步骤1:准备日期格式化工具(可选但更严谨)

先搞一个DateFormatter把日期字符串转成Date对象,这样能保证排序绝对准确,哪怕遇到不规范的日期格式也能处理:

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")

设置en_US_POSIX是为了避免不同地区的日期解析差异,让格式转换更稳定。

步骤2:将字典转成数组并排序

字典没法直接排序,我们得先把它转换成键值对数组,再对数组做排序。这里给你两种实用的排序方式:

方式一:直接按日期字符串排序(简单高效)

你的日期格式是YYYY-MM-DD,这种格式的字符串字典序和时间顺序完全一致,直接比字符串就行:

if let bpiDict = myJSON as? [String: Double] {
    // 把字典转成键值对数组并排序
    let sortedBPI = bpiDict.sorted { $0.key < $1.key }
    
    // 提取排序后的日期和价格数据
    let sortedDates = sortedBPI.map { $0.key }
    let sortedPrices = sortedBPI.map { $0.value }
    
    // 接下来就用这两个数组绘图就行
}

方式二:转成Date对象排序(更严谨)

如果担心日期格式可能出现不规范的情况(比如少了前导零的2018-1-5),用Date对象排序更稳妥:

if let bpiDict = myJSON as? [String: Double] {
    let sortedBPI = bpiDict.sorted {
        guard let date1 = dateFormatter.date(from: $0.key),
              let date2 = dateFormatter.date(from: $1.key) else {
            // 转换失败的日期默认放后面
            return false
        }
        return date1 < date2
    }
    
    let sortedDates = sortedBPI.map { $0.key }
    let sortedPrices = sortedBPI.map { $0.value }
    
    // 后续绘图逻辑
}

整合到你的代码里

修改后的完整函数如下:

func pastThirtyDaysData(money: String) {
    Alamofire.request("https://api.coindesk.com/v1/bpi/historical/close.json?currency=\(money)").responseJSON{ (dataFromAPI) in
        if dataFromAPI.result.value != nil {
            let myJSON = JSON(dataFromAPI.result.value)["bpi"].dictionaryObject
            
            let dateFormatter = DateFormatter()
            dateFormatter.dateFormat = "yyyy-MM-dd"
            dateFormatter.locale = Locale(identifier: "en_US_POSIX")
            
            if let bpiDict = myJSON as? [String: Double] {
                // 选你需要的排序方式,这里用方式二举例
                let sortedBPI = bpiDict.sorted {
                    guard let date1 = dateFormatter.date(from: $0.key),
                          let date2 = dateFormatter.date(from: $1.key) else {
                        return false
                    }
                    return date1 < date2
                }
                
                let sortedDates = sortedBPI.map { $0.key }
                let sortedPrices = sortedBPI.map { $0.value }
                
                // sortedDates就是按时间升序的X轴数据,sortedPrices对应Y轴价格
                print("排序后的日期序列:\(sortedDates)")
                // 调用你的绘图方法,传入这两个数组即可
            }
        }
    }
}

关键提醒

绘图时一定要用排序后的sortedDates和sortedPrices,绝对不能直接遍历原字典——字典的遍历顺序是随机的,这就是你之前图表X轴乱序的根本原因。

内容的提问来源于stack exchange,提问作者John Doe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:44:32