你可以使用NSSortDescriptor按值不为空进行排序吗?

时间:2012-06-19 10:18:29

标签: objective-c nsmutablearray nssortdescriptor

我有以下排序描述符,用于对我的业务对象数组进行排序,准备好在表格中显示,我开始使用previous SO question

中的一些示例排序代码
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];

我正在显示的所有对象都有一个标题。其中只有一些会有一个“awardOn”设置,这是一个NSDate。

我想做什么:

  1. 对整个数组进行排序,以便所有具有“awardOn”设置的对象都是 显示在顶部
  2. 在两个“集合”中,按字母顺序排列
  3. 我不关心约会的实际价值,我更感兴趣 如果它存在或不存在
  4. 像这样的东西(标题,大胆的那些具有awardOn的值)

    • 真棒
    • 更好
    • 另一个
    • 另一个
    • 再一次
    • 又一个

3 个答案:

答案 0 :(得分:1)

有两种可能的方式:

  1. 创建业务对象时,如果awardedOn日期不存在,则将distantPast日期指定为awardedOn,然后按title然后按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; } 进行正常排序。

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

  3. {{1}}

答案 1 :(得分:1)

你应该能够使用两个描述符,比如你先说,首先是awardOn,然后是标题。但是,您需要为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 

这将允许你必须分开集:真棒/更好/酷和另一个/另一个/一个/另一个,在你的例子中。在那之后,你应该善于:

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

最后一点,你可能需要更多的工作,这取决于你的"空" awardOn字段看起来像(我假设,在上面的代码中,字段被设置为null)。你可以看看这里:https://stackoverflow.com/a/3145789

答案 2 :(得分: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;
               }];