【问题标题】:Sort NSArray of custom objects by their NSDate properties按其 NSDate 属性对自定义对象的 NSArray 进行排序
【发布时间】:2011-08-30 07:36:29
【问题描述】:

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

以下代码生成一个数组sortedEventArray,已填充但未排序。我是以完全错误的方式解决这个问题还是我只是错过了一些小东西?

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

【问题讨论】:

  • 代码看起来非常好。你确定你有正确的密钥吗?
  • @Firoze:是的,我已经三次检查了这个名字。 “startDateTime”是我的自定义类的 NSDate 属性的名称。
  • 问题出在我的代码中的其他地方,所以我考虑关闭这个问题,但由于下面的答案很有帮助,我将把它留在这里,因为我认为其他人可能会找到它有用。

标签: objective-c cocoa sorting nsarray nsdate


【解决方案1】:

您是否尝试指定 NSDate 比较器?

例如:

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

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

【讨论】:

  • 此更改似乎没有影响我的结果。
【解决方案2】:

您确定节点事件的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,那么前后数组将有相同的顺序(因为排序操作将等同于将所有-compare:消息发送到nil,这基本上是什么都没有)。

【讨论】:

    【解决方案3】:

    好的,我知道这有点晚了,但我会这样做:

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

    显然,将 Event 替换为您的自定义对象的类。这种方法的优点是可以保护您免受未来的重构。如果您要重构 startDateTime 属性并将其重命名为其他名称,Xcode 可能不会更改您传递给排序描述符的字符串。突然之间,您的排序代码会中断/什么都不做。

    【讨论】:

    • 我同意你的看法。仅供参考,小错字。它是:“sortedArrayUsingComparator:”
    • @PaulEvans 正如我在评论中指出的那样,我正在使用 -[NSMutableArray sortUsingComparator:]。但是,我可以将其更改为返回符合 OP 示例的新排序数组。谢谢:)
    【解决方案4】:

    你可以这样实现,

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:FALSE];
    
    [self.Array sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
    

    【讨论】:

      【解决方案5】:

      你可以这样实现,

      NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"anyDateField"  ascending:YES];
      
      NSMutableArray *arr = [[array sortedArrayUsingDescriptors:[NSArray arrayWithObjects:descriptor,nil]]mutableCopy];
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-16
        相关资源
        最近更新 更多