Dav*_*vid 4 sorting cocoa objective-c nssortdescriptor
我有一个NSArrayController并且我想对内容进行排序,以便首先对具有英文字母的任何内容进行排序,然后对具有数字和非英文字符的任何内容进行排序.
例如:A,B,C ...... Z,1,2,3 ... 9,구,결,......
目前我只知道如何按字母顺序对项目进行排序.建议?
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
[dataController setSortDescriptors: [NSArray arrayWithObject: sort]];
Run Code Online (Sandbox Code Playgroud)
djr*_*ero 10
您可以使用sortedArrayUsingComparator自定义排序算法来满足您的需求.例如,您可以使用以下行给出符号优先级:
NSArray *assorted = [@"1 2 3 9 ; : ? , ? A B C Z ! á" componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSArray *sorted = [assorted sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
/* NSOrderedAscending, NSOrderedSame, NSOrderedDescending */
BOOL isPunct1 = [[NSCharacterSet punctuationCharacterSet] characterIsMember:[(NSString*)obj1 characterAtIndex:0]];
BOOL isPunct2 = [[NSCharacterSet punctuationCharacterSet] characterIsMember:[(NSString*)obj2 characterAtIndex:0]];
if (isPunct1 && !isPunct2) {
return NSOrderedAscending;
} else if (!isPunct1 && isPunct2) {
return NSOrderedDescending;
}
return [(NSString*)obj1 compare:obj2 options:NSDiacriticInsensitiveSearch|NSCaseInsensitiveSearch];
}];
Run Code Online (Sandbox Code Playgroud)
要将英文字符放在非英文字符之前,它就足以NSDiacriticInsensitiveSearch | NSCaseInsensitiveSearch作为选项使用,不需要花哨的算法.
如果你需要支持iOS而不用块试试sortedArrayUsingSelector.
通过测试另一个解决方案,如果字符串是 latin1 可编码的:
\n\ncompare:否则,如果一个以数字开头,一个以字母开头,return NSOrderingAscending则 ,如果以字母开头,则为第一个,否则NSOrderingDescending
如果两个字符串都不是拉丁字符串,请compare:再次决定
return NSOrderingAscending如果拉丁文在前,否则NSOrderingDescending 代码
\n\nNSArray *array = [NSArray arrayWithObjects:@"peach",@"apple",@"7",@"banana",@"ananas",@"5", @"papaya",@"4",@"\xea\xb5\xac",@"\xea\xb2\xb0",@"1" ,nil];\n\narray = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {\n NSString *s1 = [obj1 substringToIndex:1];\n NSString *s2 = [obj2 substringToIndex:1];\n BOOL b1 = [s1 canBeConvertedToEncoding:NSISOLatin1StringEncoding];\n BOOL b2 = [s2 canBeConvertedToEncoding:NSISOLatin1StringEncoding];\n\n if ((b1 == b2) && b1) {//both number or latin char\n NSRange r1 = [s1 rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]];\n NSRange r2 = [s2 rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]];\n if (r1.location == r2.location ) { // either both start with a number or both with a letter\n return [obj1 compare:obj2 options:NSDiacriticInsensitiveSearch|NSCaseInsensitiveSearch]; \n } else { // one starts wit a letter, the other with a number\n if ([s1 rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]].location == NSNotFound) {\n return NSOrderedAscending;\n }\n return NSOrderedDescending;\n }\n } else if((b1 == b2) && !b1){ // neither latin char\n return [obj1 compare:obj2 options:NSDiacriticInsensitiveSearch|NSCaseInsensitiveSearch];\n } else { //one is latin char, other not\n if (b1) return NSOrderedAscending;\n return NSOrderedDescending;\n }\n\n}];\nfor (NSString *s in array) NSLog(@"%@", s);\nRun Code Online (Sandbox Code Playgroud)\n\n结果
\n\nananas\napple\nbanana\npapaya\npeach\n1\n4\n5\n7\n\xea\xb5\xac\n\xea\xb2\xb0\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
4340 次 |
| 最近记录: |