通过测试的另一种解决方案,如果字符串是 latin1 可编码的:
编码
NSArray *array = [NSArray arrayWithObjects:@"peach",@"apple",@"7",@"banana",@"ananas",@"5", @"papaya",@"4",@"구",@"결",@"1" ,nil];
array = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSString *s1 = [obj1 substringToIndex:1];
NSString *s2 = [obj2 substringToIndex:1];
BOOL b1 = [s1 canBeConvertedToEncoding:NSISOLatin1StringEncoding];
BOOL b2 = [s2 canBeConvertedToEncoding:NSISOLatin1StringEncoding];
if ((b1 == b2) && b1) {//both number or latin char
NSRange r1 = [s1 rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]];
NSRange r2 = [s2 rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]];
if (r1.location == r2.location ) { // either both start with a number or both with a letter
return [obj1 compare:obj2 options:NSDiacriticInsensitiveSearch|NSCaseInsensitiveSearch];
} else { // one starts wit a letter, the other with a number
if ([s1 rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]].location == NSNotFound) {
return NSOrderedAscending;
}
return NSOrderedDescending;
}
} else if((b1 == b2) && !b1){ // neither latin char
return [obj1 compare:obj2 options:NSDiacriticInsensitiveSearch|NSCaseInsensitiveSearch];
} else { //one is latin char, other not
if (b1) return NSOrderedAscending;
return NSOrderedDescending;
}
}];
for (NSString *s in array) NSLog(@"%@", s);
结果
ananas
apple
banana
papaya
peach
1
4
5
7
구
결