4

我有以下排序描述符对我的业务对象数组进行排序,准备在表格中显示,我从上一个 SO 问题中的一些示例排序代码开始

NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"awardedOn" ascending:NO];
NSSortDescriptor *sortDescriptor2 = [[NSSortDescriptor alloc] initWithKey:@"title" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor1, sortDescriptor2, nil];
NSArray *sortedArray = [returnable sortedArrayUsingDescriptors:sortDescriptors];

我要显示的所有对象都有一个标题。只有其中一些会有一个“awardedOn”集,即 NSDate。

我想做的事:

  1. 对整个数组进行排序,以便所有带有“awardedOn”集的对象都显示在顶部
  2. 在两个“集合”中,按字母顺序排列
  3. 我不关心日期的实际值,我更感兴趣它是否存在

像这样的东西(标题,粗体的对授予的值有一个值)

  • 惊人的
  • 更好的
  • 凉爽的
  • 其他
  • 另一个
  • 多一个
  • 完后还有
4

3 回答 3

1

有两种可能的方式:

  1. 创建业务对象时,将awardedOndate 分配为distantPast好像它不存在一样,然后按正常排序awardedOn,然后按title

  2. 使用将在每个业务对象上调用的自定义比较方法创建排序描述符:

.

NSSortDescriptor *awardDescriptor = [NSSortDescriptor descriptorWithKey:@"awardedOn"
                                                              ascending:NO 
                                                               selector:@selector(compareAwardedOn:)];

// In class for business object
- (NSComparisonResult)compareAwardedOn:(id)otherBusiness {
    // return custom NSComparison result after 
    // checking whether either of awardedOn dates are nil.
    return NSOrderedSame;
}
于 2012-06-19T10:23:27.340 回答
1

您应该能够使用您首先说的两个描述符来做到这一点,首先是按奖励,然后按标题。但是,您需要为awardOn 排序提供一个自定义的NSSortDescriptor,看起来像这样:

#define NULL_OBJECT(a) ((a) == nil || [(a) isEqual:[NSNull null]]) 
@interface AwardedOnSortDescriptor : NSSortDescriptor {} 
@end 
@implementation AwardedOnSortDescriptor 
- (id)copyWithZone:(NSZone*)zone 
{ 
    return [[[self class] alloc] initWithKey:[self key] ascending:[self ascending] selector:[self selector]]; 
} 
- (NSComparisonResult)compareObject:(id)object1 toObject:(id)object2 
{ 
    if (NULL_OBJECT([object1 valueForKeyPath:[self key]])) { 
        if (NULL_OBJECT([object2 valueForKeyPath:[self key]]))  
            return NSOrderedSame; // If both objects have no awardedOn field, they are in the same "set"
        return NSOrderedDescending; // If the first one has no awardedOn, it is sorted after         
    } 
    if (NULL_OBJECT([object2 valueForKeyPath:[self key]])) { 
        return NSOrderedAscending; // If the second one has no awardedOn, it is sorted after
    } 
    return NSOrderedSame; // If they both have an awardedOn field, they are in the same "set"
} 
@end 

这将允许您必须分开集合:在您的示例中,Awesome/Better/Cool 和 Another/Another One/One More/Yet another。在那之后,你应该擅长:

NSSortDescriptor *sortDescriptor1 = [[AwardedOnSortDescriptor alloc] initWithKey:@"awardedOn" ascending:YES];
NSSortDescriptor *sortDescriptor2 = [[NSSortDescriptor alloc] initWithKey:@"title" ascending:YES];

最后一点,您可能需要做更多的工作,具体取决于您的“空”奖励字段的外观(我假设,在上面的代码中,该字段设置为空)。你可以看看这里:https ://stackoverflow.com/a/3145789

于 2012-06-25T12:03:10.460 回答
0

尝试使用比较器:

_finalArray =  [_array sortedArrayUsingComparator: ^NSComparisonResult(NSDictionary *obj1, NSDictionary *obj2) 
               {
                   if([[obj1 valueForKey@"awardedOn"] lenght] && ![[obj2 valueForKey@"awardedOn"] lenght])
                       return NSOrderedDescending;
                    if([[obj2 valueForKey@"awardedOn"] lenght] && ![[obj1 valueForKey@"awardedOn"] lenght])
                       return NSOrderedAscending;
                   return NSOrderedSame;
               }];
于 2012-06-19T10:32:36.423 回答