使用NSSortDescriptor在排序结束时放置空字符串的简便方法?

时间:2012-03-16 20:11:53

标签: ios sorting nsdictionary nssortdescriptor

我正在使用NSSortDescriptorNSArrayNSDictionary项进行排序。工作得很好,正是我所需要的......除了我想要的是我的排序键的空白值的字典项目显示在排序列表的末尾。有没有办法轻松完成这个?或者我是否必须创建一些自定义排序功能?不,我不想只是将它设置为DESC顺序......我希望将结果排序为A,A,B,B,C,空白,空白。

3 个答案:

答案 0 :(得分:2)

使用自定义比较查看另一个示例后想出来。这是我最终得到的代码:

@interface NSString (CustomStatusCompare)
- (NSComparisonResult)customStatusCompare:(NSString*)other;
@end

@implementation NSString (CustomStatusCompare)
- (NSComparisonResult)customStatusCompare:(NSString*)other {
    NSAssert([other isKindOfClass:[NSString class]], @"Must be a NSString");
    if ([self isEqual:other]) {
        return NSOrderedSame;
    }
    else if ([self length] > 0 && [other length] > 0) {
        return [self localizedCaseInsensitiveCompare:other];        
    }
    else if ([self length] > 0 && [other length] == 0) {
        return NSOrderedAscending;
    }
    else {
        return NSOrderedDescending;
    } 
}
@end



NSSortDescriptor *serviceTypeDescriptor =
[[NSSortDescriptor alloc] initWithKey:@"Service"
                             ascending:YES
                             selector:@selector(localizedCaseInsensitiveCompare:)];

NSSortDescriptor *locationDescriptor = 
[[NSSortDescriptor alloc] initWithKey:@"Location"
                             ascending:YES
                             selector:@selector(customStatusCompare:)];  //using custom comparison here!

NSArray *descriptors = [NSArray arrayWithObjects:locationDescriptor, nameDescriptor, nil];        
self.navArray = [self.navArray sortedArrayUsingDescriptors:descriptors];

因此,如果两个字符串都为空,则比较器返回NSOrderedSame ...如果两个字符串都为非空,则调用常规比较函数...如果只有一个字符串为空,则它会反转该比较的正常顺序。瞧!

答案 1 :(得分:0)

使用NSNumericSort而不是NSDiacriticInsensitive或NSCaseInsensitive进行排序。由于ascii代码中的空格大概是256,因此它将被发送到列表的后面。

答案 2 :(得分:0)

编辑:我误解了这个问题,并认为目的是按顺序排列带有前导空格的字符串(无论如何都应该这样)。

我想,你想要这样的东西。这是完全未经测试的,并且不考虑多个前导空格。我确信这是一种更优雅的方式,但它应该完成工作。

NSArray *sortedArray = [array sortedArrayUsingComparator: ^(id obj1, id obj2) {
    NSString *str1 = (NSString *)obj1;
    NSString *str2 = (NSString *)obj2;

    BOOL str1HasSpace = [str1 hasPrefix:@" "];
    BOOL str2HasSpace = [str2 hasPrefix:@" "];

    if (str1HasSpace && !str2HasSpace) {
        return NSOrderedAscending;
    } else if (str2HasSpace && ! str1HasSpace) {
        return NSOrderedDescending;
    } else {
        return [[str1 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] compare:[str2 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
    }
}];