Easy way to put blank strings at end of sort using NSSortDescriptor?

牧云@^-^@ 提交于 2019-12-24 01:57:25

问题


I'm using NSSortDescriptor to sort an NSArray of NSDictionary items. Works great, just what I needed... except that I'd like for the dictionary items that have blank values for my sort key to show up at the end of the sorted list. Is there a way to easily accomplish this? Or will I have to create some custom sorting functions? And no, I don't want to just set it to DESC order... I'd like sorted results to look like A, A, B, B, C, blanks, blank.


回答1:


Figured this out after seeing another example using a custom comparison. Here is the code I ended up with:

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

So the comparer returns NSOrderedSame if both strings are empty... calls the regular comparison function if both strings are non-empty... if only one string is empty, it reverses the normal order of that comparison. Voila!




回答2:


Do the Sort using NSNumericSort instead of NSDiacriticInsensitive or NSCaseInsensitive. Since the whitespace is probably 256 in ascii code it will be sent to the back of the list.




回答3:


Edit: I misread the question and thought the intent was to put strings with leading spaces first in sort order (which they should anyway).

You want something like this, I think. This is completely untested and doesn't take multiple leading spaces into account. I'm sure there's a more elegant way, but it should get the job done.

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


来源:https://stackoverflow.com/questions/9743890/easy-way-to-put-blank-strings-at-end-of-sort-using-nssortdescriptor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!