2012-06-19 51 views
4

我必须要显示在表格中那种我的业务对象的数组,准备下面的排序描述符,我从previous SO question你可以使用NSSortDescriptor进行排序的值不为null吗?

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]; 

是我的对象开始与一些示例代码进行排序m显示全部将有一个标题。只有其中一些会有一个“颁奖的”集,这是一个NSDate。

我想要做什么:

  1. 排序整个数组,因此所有与“awardedOn”集中的对象显示在顶部
  2. 中的两个“套” ,责令其按字母顺序
  3. 我不关心日期的实际价值,我更感兴趣的 如果它存在与否

像这样的东西(头衔,大胆的人有awardedOn

  • 真棒值)
  • 更好
  • 另一个
  • 另外一个
  • 还有一个
  • 然而,另一个

回答

1

您应该能够通过awardedOn做到这一点使用两个描述像你先说,首先,再由称号。但是,您需要为awardedOn提供一个自定义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 

这将让你有分离集:真棒/更好/酷和另一个/另1个/ 1更多/在另一个例子中。在这之后,你要善于用:

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

最后要注意,你可能需要一个豆蔻更多的工作,这取决于你的“空” awardedOn领域的样子(我以为,在上面的代码,该字段被设置为空)。你可以看看这里:https://stackoverflow.com/a/3145789

+1

我写过一个基于Swift中的这个答案的类。 https://gist.github.com/evgeniyd/d974121b94b17931480c –

+0

这是真棒尤金!谢谢:) 我还建议你添加另一个有空的对象在升序为真时。 – ameunier

1

有两种可能的方式:

  1. 当创建一个业务对象,分配awardedOn日期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; 
} 
+0

这是如何考虑到对标题的排序呢? – Jimmy

+0

不同的属性使用不同的排序描述符。您将一组描述符传递给一组业务对象。 – Eimantas

0

尝试使用比较:

_finalArray = [_array sortedArrayUsingComparator: ^NSComparisonResult(NSDictionary *obj1, NSDictionary *obj2) 
       { 
        if([[obj1 [email protected]"awardedOn"] lenght] && ![[obj2 [email protected]"awardedOn"] lenght]) 
         return NSOrderedDescending; 
        if([[obj2 [email protected]"awardedOn"] lenght] && ![[obj1 [email protected]"awardedOn"] lenght]) 
         return NSOrderedAscending; 
        return NSOrderedSame; 
       }]; 
+0

不考虑'title' – Jimmy

+0

每个'lenght'都应该是'length'并且在每个'valueForKey'后面都会有一个冒号':'valueForKey:@“awardsOn”' – Salim

相关问题