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

如何按顺序从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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:05:13