如何通过包含时间字符串的键值对NSDictionary进行正确排序?

时间:2014-12-05 21:55:09

标签: ios objective-c nsdictionary

我不明白为什么它没有正确排序。我有一个NSDictionary,其中包含当天时间的关键值。当我尝试对它进行排序时,它没有正确排序。

events = @{@"12:00 PM" : @[@"1"],
           @"12:30 PM" : @[@"2"],
           @"1:00 PM" : @[@"3", @"4"],
           @"1:30 PM" : @[@"5", @"11"],
           @"2:00 PM" : @[@"6"],
           @"3:00 PM" : @[@"7"],
           @"3:30 PM" : @[@"8"],
           @"4:00 PM" : @[@"9"],
           @"4:30 PM" : @[@"10", @"11"],
           @"5:00 PM" : @[@"12", @"13", @"14"]};

eventTimes = [ [events allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

当我NSLog eventTimes时,它产生输出:

  

(       “1:00 PM”,       “下午1:30”,       “12:00 PM”,       “下午12:30”,       “下午2点”,       “下午3:00”,       “下午3:30”,       “4:00 PM”,       “下午4:30”,       “下午5:00”)

如何实现此输出?

  

(       “12:00 PM”,       “下午12:30”,       “1:00 PM”,       “下午1:30”,       “下午2点”,       “下午3:00”,       “下午3:30”,       “4:00 PM”,       “下午4:30”,       “下午5:00”)

更新:我试过了:

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"] ];
[formatter setDateFormat:@"HH:mm"];
NSString *etaStr = [eventTimes objectAtIndex:section];
NSDate *generatedDate = [formatter dateFromString:etaStr];
NSLog(@"%@", [formatter stringFromDate:generatedDate]);

但是,我没有。

3 个答案:

答案 0 :(得分:1)

  1. 将时间保持为秒数,时间戳或NSDate
  2. 使用常规排序。
  3. 使用NSDateFormatter以首选格式生成时间字符串。通常将您的应用程序数据保留为对内部数据组织友好的格式,并在将其显示在屏幕上之前进行格式化。
  4. 关于NSDateFormatter问题以及如何将时间字符串转换为NSDate,我在Playground玩游戏,似乎关键是设置ShortStyle格式的时间,设置{{1 locale,因为你从12小时转换,并确保你使用en_US时区来避免任何时间偏移,因为你的时间无论如何都是绝对的。

    UTC

    现在所有这些都在Swift中,但我确信它足够直观,可以在Objective-C中编写相同的代码。

    控制台输出:

    // Playground - noun: a place where people can play
    
    import UIKit
    
    // Input
    var times = [
        "3:30 PM", "4:00 PM", "4:30 PM",
        "5:00 PM", "12:30 PM", "12:00 PM",
        "1:00 PM", "1:30 PM", "2:00 PM",
        "3:00 PM"
    ]
    
    // Create array of NSDate objects
    var dates = NSMutableArray()
    
    println("Convert time string to NSDate")
    println()
    
    // Setup formatter for the US time style
    let formatter = NSDateFormatter()
    formatter.dateFormat = "h:mm a"
    formatter.dateStyle = NSDateFormatterStyle.NoStyle
    formatter.timeStyle = NSDateFormatterStyle.ShortStyle
    formatter.timeZone = NSTimeZone(name: "UTC")
    formatter.locale = NSLocale(localeIdentifier: "en_US")
    
    // Loop thru input data and convert time string to NSDate
    for t in times {
        let date = formatter.dateFromString(t)
    
        dates.addObject(date!)
    
        println("t = \(t) converted as \(date)")
    }
    
    println()
    println("Sort array of NSDate objects")
    println()
    
    // Sort dates
    let sortedDates = dates.sortedArrayUsingDescriptors([ NSSortDescriptor(key: "self", ascending: true) ])
    
    // Print out sorted array of dates
    for d in sortedDates {
        let date = d as NSDate
        let formattedString = formatter.stringFromDate(date)
        println("\(formattedString)")
    }
    

答案 1 :(得分:1)

您的密钥是字符串,您正在对字符串进行按字典顺序比较。在该比较中,1:00小于12:30,因为:小于2

如果要按日期排序,首先需要将其转换为实际可以在转换中传达时间值的类型。这可以是NSDate,也可以是表示午夜偏移的简单整数。

答案 2 :(得分:0)

一个简单的比较器可以做

NSArray *sortedAllKeys = [[events allKeys] sortedArrayUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) {
    static NSDateFormatter *formatter;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        formatter = [[NSDateFormatter alloc] init];
        formatter.dateFormat =@"h:mm a";
        [formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US.POSIX"] ];
    });
    return [[formatter dateFromString:obj1] compare:[formatter dateFromString:obj2]];
}];

Technical Note QA1480可能对你有用。