【问题标题】:Sorting NSArray which contain array of dictionaries - Sort as per "Date" key排序包含字典数组的 NSArray - 按“日期”键排序
【发布时间】:2015-05-27 10:27:11
【问题描述】:

我有以下 NSArray,它在每个索引处包含一个字典,这是内容,只提供前 3 条记录-

[
            {

                "postDate": "4/11/2011 2:03:33 PM",
                "imageLink": "",
                "eventLink": "www.google.com"
            },
            {

                "postDate": "6/16/2011 1:42:45 PM",
                "imageLink": "",
                "eventLink": "www.google.com"
            },
            {

                "postDate": "9/21/2011 10:22:34 AM",
                "imageLink": "",
                "eventLink": "www.google.com"
            }
]

注意:- postDate 只是一个 NSString,它不是 NSDate 类型,但我必须根据这个键执行排序。

我的任务是根据“postDate”键对数组进行排序,这意味着整个数组将按日期排序(升序/降序)。

我使用了以下代码,但没有帮助,因为 arr 正在存储来自 arrEventsData 的所有数据,但没有进行排序:-

NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"postDate"  ascending:YES];

    NSMutableArray *arr = [[arrEventsData sortedArrayUsingDescriptors:[NSArray arrayWithObjects:descriptor,nil]]mutableCopy]; 

任何想法或解决方案都会有所帮助。

谢谢

【问题讨论】:

  • 那些不是日期,它们是字符串。
  • 是的,它们是字符串。我无法更改它,因为它来自后端。
  • 不能改吗?
  • 我的意思是我可以通过在我的程序中将 postDate 键值更新为 Nsdate 格式来手动更改它,但不能从服务器端更改它。
  • 这听起来像是朝着正确方向迈出的一步......

标签: ios objective-c iphone arrays sorting


【解决方案1】:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"M/dd/yyyy H:mm:ss a"];

NSArray *sortedByDates = [arr sortedArrayUsingComparator:^NSComparisonResult(NSDictionary *obj1, NSDictionary *obj2)
{
    NSDate *date1 = [dateFormatter dateFromString:obj1[@"postDate"]];
    NSDate *date2 = [dateFormatter dateFromString:obj2[@"postDate"]];
    return [date1 compare:date2];
}];
NSLog(@"Sorted Array : %@",sortedByDates);

【讨论】:

    【解决方案2】:

    像这样:

        NSMutableArray *sortedArray = [arr sortedArrayUsingComparator:^NSComparisonResult(NSDictionary *obj1, NSDictionary *obj2) {
            NSDate *d1 = [self stringToDate:obj1[@"postDate"]];
            NSDate *d2 = [self stringToDate:obj2[@"postDate"]];
            return [d1 compare:d2];
        }];
    

    对于“stringToDate”方法,但是您想实现它,请在此处查看另一个 SO 答案:Convert NSString of a date to an NSDate

    编辑:正如@Droppy 所指出的,一旦数据从服务器到达,最好将字符串解析为 NSDate。这可以防止在排序中进行昂贵的重复转换,并且无论如何可能都更有用。

    【讨论】:

    • 我确信这会奏效,但字符串到日期的重复转换会使其变得昂贵。
    • (如果您遵循链接的代码并每次都创建一个新的NSDateFormatter,则更是如此)。
    • 当然。但这取决于您有多少记录,这是否会导致问题。如果确实如此,则有多种方法可以缓存转换。也不为他这样做;)
    • ... 例如,一经解析就将数据转换为自定义对象?
    • 是的,这是一种选择。花尽可能多的时间来使 stringToDate 方法尽可能快速和高效。如果我一次处理 10 条记录,我根本不会打扰。如果有100个,也许。如果有 1000 个,当然。
    【解决方案3】:

    您必须从这些 NSString 中创建 NSDate 对象才能使 compare 工作

    创建一个静态 NSDateFormatter,因为它们的创建成本很高:

    NSArray *sortedArray = [array sortedArrayUsingComparator:^NSComparisonResult(NSDictionary *a, NSDictionary *b) {
    
            static NSDateFormatter *dateFormatter = nil;
            static dispatch_once_t onceToken;
            dispatch_once(&onceToken, ^{
                dateFormatter = [[NSDateFormatter alloc] init];
                [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; //Set correct format here
            });
    
            NSDate *first = [dateFormatter dateFromString:[a objectForKey:@"postDate"]];
            NSDate *second = [dateFormatter dateFromString:[b objectForKey:@"postDate"]];
            return [first compare:second];
        }];
    

    【讨论】:

      猜你喜欢
      • 2020-06-09
      • 2020-04-08
      • 2016-07-24
      • 2020-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-19
      相关资源
      最近更新 更多