对日期字符串或对象的NSArray进行排序


86

我有一个NSArray包含日期字符串例如NSString)的控件,例如:“ Thu,2009年5月21日19:10:09 -0700”

我需要NSArray按日期排序。我考虑过NSDate先将日期字符串转换为对象,但在如何按NSDate对象排序方面陷入困境。

谢谢。


由于这与Foundation框架相关,而不是特定于iPhone,因此已重新标记。
奎因·泰勒,

Answers:


110

将日期作为NSDate对象存储在NS(Mutable)Array中,然后使用-[NSArray sortedArrayUsingSelector:-[NSMutableArray sortUsingSelector:]@selector(compare:)作为参数。该-[NSDate compare:]方法将为您按升序排列日期。这比创建一个NSSortDescriptor更加简单,并且比编写自己的比较函数要简单得多。(NSDate对象知道如何至少与我们希望使用自定义代码完成的效率一样有效地相互比较。)


11
目前尚不清楚最初的问题是询问排序日期数组还是对具有日期字段的对象数组进行排序。如果是前者,这是最简单的方法,但是如果是后者,则是使用NSSortDescriptor的方法。
smorgan

@smorgan NSSortDescriptor如何处理零个日期?
Ash

感谢您的帮助,我认为我们应该在Apple Docs中阅读更多内容,但直到您使用它为止,它似乎是如此无聊。
Abo3atef

1
您能否以示例代码的形式显示此示例?提前致谢。
uplearnedu.com 2014年

115

如果我NSMutableArray的对象具有类型为“ beginDate”的字段,则NSDate使用NSSortDescriptor以下对象:

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"beginDate" ascending:TRUE];
[myMutableArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];

3
我知道已经过去了很多时间(当以前的答案被接受时,可能还没有NSSortDescriptor),但是对于将来的使用,这应该是正确的答案。
Vive 2012年

1
这是一个很棒的解决方案。用几行代码解决了我的问题。感激一吨@vinzenzweber
Pratyusha Terli

1
真的...我真的为第一次试运行感到震惊!我以为initWithKey是保留给定义了键的字典的,但是您要做的就是引用对象数组中的属性?让光芒照耀着vinzenzweberskavitchski!
whyoz 2012年

NSSortDescriptor自2003年底的OS X 10.3开始问世。这是一个稍有不同的方案,其中date是另一个对象中的一个字段。使用更现代的API,您不妨使用-[NSMutableArray sortUsingComparator:](10.6+)并传递一个返回-compare:两个字段调用结果的块。它可能比调用-valueForKey:每个对象更快。您甚至可以使用-sortWithOptions:usingComparator:和传递选项来同时进行排序。
奎因·泰勒

上面的NSSortDescriptor如何处理零日期?如果需要,我们是否需要告诉清算人如何处理他们?
Ash

17

您还可以使用类似以下的内容:

//Sort the array of items by  date
    [self.items sortUsingComparator:^NSComparisonResult(id obj1, id obj2){
        return [obj2.date compare:obj1.date];
    }];

但这确实假定该日期存储为,NSDate而该日期NString应该没有问题。最好是,我建议也以原始格式存储数据。在这种情况下更易于操作。


9

您可以使用块进行适当排序:

sortedDatesArray = [[unsortedDatesArray sortedArrayUsingComparator: ^(id a, id b) {
    NSDate *d1 = [NSDate dateWithString: s1];
    NSDate *d2 = [NSDate dateWithString: s2];
    return [d1 compare: d2];
}];

建议您将所有字符串转换为日期,然后再排序,以使转换次数不超过日期项。任何排序算法都将为您提供比数组中的项目数更多的字符串到日期的转换(有时要多得多)

有关块排序的更多信息:http : //sokol8.blogspot.com/2011/04/sorting-nsarray-with-blocks.html


这是@notoop提出的次优想法的变体。无论如何,绝对要先转换为NSDate。
奎因·泰勒

他基本上只是把我的回答与@ notoop的答案.....完全没有必要双岗这些,如果你问我....
TheCodingArt

这比将日期字符串解析为NSDate数组然后对NSDate数组进行排序要慢得多,因为cos将有2 *(n-1)倍的额外字符串解析。解析字符串通常在CPU上是繁重的工作。
CarlLee 2014年

5

对于我而言,它的工作原理如下:

    NSArray * aUnsorted = [dataToDb allKeys];
    NSArray * arrKeys = [aUnsorted sortedArrayUsingComparator:^ NSComparisonResult(id obj1,id obj2){
        NSDateFormatter * df = [[NSDateFormatter alloc] init];
        [df setDateFormat:@“ dd-MM-yyyy”];
        NSDate * d1 = [df dateFromString:(NSString *)obj1];
        NSDate * d2 = [df dateFromString:(NSString *)obj2];
        返回[d1比较:d2];
    }];

我有一本字典,其中所有键的日期都以dd-MM-yyyy格式表示。并且allKeys返回未排序的字典键,我想按时间顺序显示数据。


5

您可以使用sortedArrayUsingFunction:context:。这是一个示例:

NSComparisonResult dateSort(NSString *s1, NSString *s2, void *context) {
    NSDate *d1 = [NSDate dateWithString:s1];
    NSDate *d2 = [NSDate dateWithString:s2];
    return [d1 compare:d2];
}

NSArray *sorted = [unsorted sortedArrayUsingFunction:dateSort context:nil];

使用时NSMutableArray,您可以sortArrayUsingFunction:context:改用。


9
这是一个坏主意-比较函数应该很快,并且不必为每次比较都从字符串创建NSDate对象。如果您已经在使用-[NSDate compare:],只需将日期存储在数组中,然后直接使用-sortedArrayUsingSelector:。
奎因·泰勒

我认为,如果要对已经具有NSDate字段的对象进行排序,这是一个很好的解决方案。没有?
GnarlyDog 2012年

1
如果数组已经包含NSDate对象,则可以使用上面的答案,甚至可以使用-[NSMutableArray sortUsingComparator:]10.6中添加的。
奎因·泰勒

如果您使用的字典数组中有一个日期字符串值对象(如NSString)以及一些其他密钥值对象,则此解决方案是迄今为止最好的解决方案。只需在dateSort函数内部进行一些修改。竖起大拇指!:)
Erfan 2015年

4

有了后NSDate,您可以创建一个NSSortDescriptorwith initWithKey:ascending:,然后使用sortedArrayUsingDescriptors:进行排序。


这种方法可以使用,但是使用-sortedArrayUsingSelector:会更简单,并且不需要创建额外的对象。
奎因·泰勒

在进行预编辑时,该问题提到了“日期键”,因此我认为这实际上是一组将日期作为一个字段的对象/字典,而不是原始日期的数组。在那种情况下,sortedArrayUsingSelector:比较复杂,因为它需要编写一个自定义的排序例程来进行查找。
smorgan

是的,对于任何混乱,我们深表歉意。因为他只是说他正在用“ date”键存储数组,所以我整理了一下引用,我意识到这使问题变得更加混乱。考虑到更复杂的数据结构,您绝对对相对复杂性是正确的。
奎因·泰勒


1

改变这个

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"beginDate" ascending:TRUE];
[myMutableArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Date" ascending:TRUE];
[myMutableArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];

只需更改密钥:它必须Date始终

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.