如何按顺序从NSDictionary中获取键?附JSON响应示例
如何按顺序从NSDictionary中获取键?
首先要明确:默认情况下,iOS 10及更早版本的NSDictionary是无序集合,它不会保留JSON响应里的键顺序;即使iOS 11+之后系统字典会保留插入顺序,也不建议依赖这个特性——因为你的键是有明确时间逻辑的日期范围,最可靠的方式是手动对键按日期排序来获取顺序。
下面是两种可行的解决方案,推荐第一种跨版本兼容的方式:
方法1:手动按日期顺序排序键(推荐,全版本兼容)
你的键是类似"2018-02-27 to 2018-03-05"的日期范围字符串,我们可以提取每个键的起始日期,转成可比较的日期对象后排序,再按排序后的顺序遍历字典。
Objective-C 实现代码
// 假设你已经通过JSONSerialization解析好响应数据 NSDictionary *responseDict = ...; NSDictionary *graphDataDict = responseDict[@"graphdata"]; // 获取所有日期范围键 NSArray *allDateKeys = [graphDataDict allKeys]; // 对键进行排序:提取起始日期,转成NSDate后比较先后 NSArray *sortedDateKeys = [allDateKeys sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull key1, id _Nonnull key2) { // 拆分日期范围,取出起始日期字符串 NSString *startDateStr1 = [[key1 componentsSeparatedByString:@" to "] firstObject]; NSString *startDateStr2 = [[key2 componentsSeparatedByString:@" to "] firstObject]; // 初始化日期格式化器(必须设置locale避免地区解析问题) NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; dateFormatter.dateFormat = @"yyyy-MM-dd"; dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; NSDate *date1 = [dateFormatter dateFromString:startDateStr1]; NSDate *date2 = [dateFormatter dateFromString:startDateStr2]; return [date1 compare:date2]; }]; // 按排序后的顺序遍历字典 for (NSString *dateRangeKey in sortedDateKeys) { NSDictionary *periodData = graphDataDict[dateRangeKey]; // 在这里处理每个时间段的数据,比如取出historical、datewise等值 NSLog(@"时间段:%@,历史值:%@", dateRangeKey, periodData[@"historical"]); }
Swift 实现代码
// 假设你已经获取到JSON数据并完成解析 guard let responseDict = try? JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any], let graphDataDict = responseDict["graphdata"] as? [String: [String: Any]] else { // 解析失败的处理逻辑 return } // 对日期范围键进行排序 let sortedDateKeys = graphDataDict.keys.sorted { keyA, keyB in // 提取起始日期字符串 let startDateStrA = keyA.components(separatedBy: " to ").first ?? "" let startDateStrB = keyB.components(separatedBy: " to ").first ?? "" // 初始化日期格式化器 let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd" dateFormatter.locale = Locale(identifier: "en_US_POSIX") guard let dateA = dateFormatter.date(from: startDateStrA), let dateB = dateFormatter.date(from: startDateStrB) else { return false } // 按日期升序排列 return dateA < dateB } // 按顺序遍历处理数据 for dateRangeKey in sortedDateKeys { if let periodData = graphDataDict[dateRangeKey] { print("时间段:\(dateRangeKey),历史值:\(periodData["historical"] ?? "无数据")") // 处理你的业务逻辑 } }
方法2:依赖iOS11+的字典插入顺序(仅高版本)
如果你的APP只需要支持iOS 11及以上版本,那么JSONSerialization解析出来的字典会保留JSON中的原始键顺序,这时候你可以直接遍历graphDataDict.allKeys(OC)或者graphDataDict.keys(Swift)来获取顺序。但注意:这种方式依赖系统实现,一旦JSON生成方调整键的顺序,或者解析选项有变化,结果可能不符合预期,所以仅在明确不需要兼容旧版本且信任JSON顺序的情况下使用。
注意事项
- 日期格式化器一定要设置
locale为en_US_POSIX,否则在非英文地区可能出现日期解析失败的问题 - 如果你的日期范围格式有变动,需要对应调整拆分字符串的逻辑
内容的提问来源于stack exchange,提问作者Shivam Tripathi
相关产品推荐
相关产品推荐

