在开发过程中经常碰见中文排序,例如通讯录列表、城市列表等等。一开始解决方法。解决思路根据每个中文的对应的唯一的值,在数组中获取中文的首字母。主要的代码:
char pinyinFirstLetter(unsigned short hanzi)
{
int index = hanzi - HANZI_START;
if (index >= 0 && index <= HANZI_COUNT)
{
return firstLetterArray[index];
}
else
{
return hanzi;
}
}
代码中的 firstLetterArray
就是存储了中文的首字母的数组。然而这个方法有一个缺陷,没有解决中文中多音字的问题。如“重庆”(chong qing)首字母应该是cq,但是程序获得的是 zq。为了解决这个问题,重新找到了下面的另一个解决方法。主要代码:
///处理多音字排序的问题
+(NSMutableArray *)pinYinHeteronySortWith:(NSArray *)unorderedArray{
NSMutableArray *pinYinArray=@[].mutableCopy;
NSMutableDictionary *dictXiaBiao = @{}.mutableCopy;
//第一步是转成拼音
[unorderedArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSString *stringUnordered = (NSString *)obj;
NSMutableString *mutStringPinYin=@"".mutableCopy;
for (NSInteger i=0; i<stringUnordered.length; i++) {
//首先把字符串UniChar编码一下
UniChar cc = [stringUnordered characterAtIndex:i];
//检查该unicode码是否在处理范围之内,在则返回该码对映汉字的拼音首字母,不在则调用其它函数处理
//首先查找多音字,这个地方需要手动去搜集,耗时很大
if (cc < 40869 && cc > 19968) {
NSString *ccString = [NSString stringWithFormat:@"%d",cc];
// NSLog(@"UniChar编码: %d",cc);
NSString *duoYinZi =[PinYinHeterony heteronymSortDictonary][ccString];
if (duoYinZi) {
//走到这个地方就是多音字了,这个地方需要处理一下多音字到底读哪一个首字母
NSString *hh = [PinYinHeterony heteronymPhraseDictonaryWith:stringUnordered];
NSAssert(hh, @"你应该向:heteronymPhraseDictonaryWith方法中添加多音字的首字母了");
mutStringPinYin = @"".mutableCopy;
[mutStringPinYin appendString:hh];
break;
}else{
[mutStringPinYin appendString:[NSString stringWithFormat:@"%c",[[PinYinHeterony chineseToPinYinBJDX] characterAtIndex:[ccString integerValue]-19968]]];
}
// NSLog(@"转成拼音了: %@",stringPinYin);
}else{
NSLog(@"不在汉字范围内所以没办法转拼音");
// NSAssert(NO, @"你应该向:heteronymPhraseDictonaryWith方法中添加多音字的首字母了");
}
}
[pinYinArray addObject:mutStringPinYin];
[dictXiaBiao setObject:obj forKey:mutStringPinYin];
}];
[pinYinArray sortUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
return [obj1 compare:obj2]==NSOrderedDescending;
}];
NSLog(@" %@",pinYinArray);
NSMutableArray *relutArray = @[].mutableCopy;
[pinYinArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
[relutArray addObject:dictXiaBiao[obj]];
}];
return relutArray;
}
这个方法的处理和上面的方法基本一样只是多出了一个多音字的数组,该多音字字典需要自己手动添加。根据字典中的key(中文)获取value(设置的首字母),例如:@[@"重庆":@"CQ"]
。这个方法虽然解决上面的问题,但是每次遇到多音字都需要自己去添加。
重点来了:
今天看了KKBox的开发教材,知道了其实Apple自己为我们提供了排序方法:localizedCompare:
。localizedCompare:
是Apple提供的根据目前系统语言决定的排序方法,在中文简体时可以进行多音字的排序。所以只需要[stringArr sortedArrayUsingSelector:@selector(localizedCompare:)];
就可以解决排序问题。
NSArray *stringArr = @[@"我们",@"我的", @"重点", @"重庆", @"三"];
NSArray *result = [stringArr sortedArrayUsingSelector:@selector(localizedCompare:)];
NSLog(@"%@", result);
输出:
(
"重庆",
"三",
"我的",
"我们",
"重点"
)