Swift macOS读取JSON文件转字典 字符串转日期后按日期排序
实现方案
核心思路
- 新增业务实体结构体存储单条时间序列数据,同时携带Date类型的日期和对应NAV值,避免字典的无序问题
- 配置匹配
yyyyMMdd格式的日期转换器,将原字典的字符串键批量转为Date类型 - 解码完成后统一做数据转换、清洗、排序,直接输出可直接使用的有序数组
完整修改代码
import Foundation import Combine // 原有解码模型保持不变 struct TimeSeriesValue: Decodable { let value : Double enum CodingKeys: String, CodingKey { case value = "NAV" } } // 新增业务层模型,携带Date类型日期 struct TimeSeriesEntry: Identifiable { let id = UUID() let date: Date let nav: Double } // 数据管理类(原类名调整为大写开头符合Swift命名规范) class TimeSeriesDataManager: ObservableObject { // 对外暴露已排序的时间序列数组,可直接用于列表渲染等场景 @Published var sortedSeries: [TimeSeriesEntry] = [] // 日期转换器全局复用 private let dateFormatter: DateFormatter = { let formatter = DateFormatter() formatter.dateFormat = "yyyyMMdd" formatter.locale = Locale(identifier: "en_US_POSIX") return formatter }() init() { loadSingleFile(fileName: "JSONDataPrincipal") // 如果要加载多份文件,重复调用loadSingleFile传入不同文件名即可,最后统一排序 // loadSingleFile(fileName: "其他JSON文件名") sortSeries() } private func loadSingleFile(fileName: String) { guard let url = Bundle.main.url(forResource: fileName, withExtension: "json") else { print("Json文件\(fileName)未找到") return } let decoder = JSONDecoder() do { let data = try Data(contentsOf: url) let rawDict = try decoder.decode([String:TimeSeriesValue].self, from: data) // 转换字符串键为Date for (dateStr, value) in rawDict { guard let date = dateFormatter.date(from: dateStr) else { print("日期格式异常:\(dateStr),已跳过") continue } sortedSeries.append(TimeSeriesEntry(date: date, nav: value.value)) } } catch { print("文件\(fileName)解码失败:\(error)") } } // 按日期升序排序,要降序的话把 < 改成 > 即可 private func sortSeries() { sortedSeries.sort { $0.date < $1.date } } } // 上层调用层 struct JSONModelPrincipal { @ObservedObject var prinJSONData = TimeSeriesDataManager() }
补充说明
如果需要多文件合并,只需要在init方法里多次调用loadSingleFile传入不同的JSON文件名,所有数据加载完成后调用一次sortSeries即可完成全量数据的排序。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

