按照NSDate属性对自定义对象的NSArray进行排序

16

我正在尝试对一个由自定义对象填充的NSArray进行排序,每个对象都有一个类型为NSDate的属性startDateTime

以下代码会生成一个名为sortedEventArray的数组,但其未被排序。我是在完全错误的方向上还是只是错过了一些小东西?

NSSortDescriptor *dateDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"startDateTime" 
                                                                 ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:dateDescriptor];
NSArray *sortedEventArray = [nodeEventArray sortedArrayUsingDescriptors:sortDescriptors];

代码看起来完全没问题。你确定你有正确的密钥吗? - Firoze Lafeer
@Firoze:是的,我已经三次检查了名称。“startDateTime”是我自定义类上的NSDate属性的名称。 - markdorison
2
问题最终在我的代码其他地方出现了,所以我考虑关闭这个问题,但由于下面回答的有用性质,我决定将其保留在这里,因为我认为其他人可能会发现它有用。 - markdorison
5个回答

25

您确定节点事件的startDateTime实例变量非空吗?

如果您还没有,则可以为节点事件对象添加一个(自定义)-description方法,类似于以下操作:

- (NSString *)description {
   return [NSString stringWithFormat:@"%@ - %@",
                   [super description], startDateTime]];
}

然后在您的排序代码中记录数组在排序前和排序后的状态:

NSLog(@"nodeEventArray == %@", nodeEventArray);
NSSortDescriptor *dateDescriptor = [NSSortDescriptor
                                     sortDescriptorWithKey:@"startDateTime" 
                                                 ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:dateDescriptor];
NSArray *sortedEventArray = [nodeEventArray
         sortedArrayUsingDescriptors:sortDescriptors];
NSLog(@"sortedEventArray == %@", sortedEventArray);
如果所有的 startDateTime 都是 nil,那么 before 和 after 数组将会有相同的顺序(因为排序操作相当于向nil发送所有的 -compare: 消息,而这基本上什么也不做)。

11

你尝试过通过指定NSDate比较器吗?

例如:

NSSortDescriptor *dateDescriptor = [NSSortDescriptor
   sortDescriptorWithKey:@"startDateTime"
   ascending:YES
   selector:@selector(compare:)];

这应该强制使用NSDate类的正确比较器。


1
这个更改似乎没有影响到我的结果。 - markdorison

11

好的,我知道这有点晚了,但这是我会做的方法:

NSArray *sortedEventArray = [events sortedArrayUsingComparator:^NSComparisonResult(Event *event1, Event *event2) {
    return [event1.startDateTime compare:event2.startDateTime];
}];

显然,将Event替换为您自定义对象的类名。这种方法的优点是,您可以防止未来的重构。如果您要重构并将startDateTime属性重命名为其他名称,Xcode可能不会更改您传递到排序描述符的字符串。突然间,您的排序代码将无法正常工作。


我同意你的看法。顺便提一下,有一个小笔误。正确的写法是:"sortedArrayUsingComparator:"。 - Paul Evans
@PaulEvans 我正在使用 -[NSMutableArray sortUsingComparator:],正如我在评论中提到的那样。但是,我可以根据 OP 的示例更改它以返回一个新的排序数组。谢谢 :) - slottermoser

0

你可以像这样实现:

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:FALSE];

[self.Array sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];

0
你可以像这样实现:
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"anyDateField"  ascending:YES];

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接