问题
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