在实现好友列表或通讯录功能时,我们大多需要对名字进行拼音排序及分组,后来在网上发现了YUChineseSorting已经实现了基本的字符串排序算法。但是它只能对字符串数组进行分组排序,并且还需要加入.cpp文件,使用比较麻烦。于是我在原来基础上对代码进行封装,支持了对对象数组按对象的某个属性进行排序。并对原来的代码进行了合并和封装,比原来使用更方便。
原理
在Objective C语言中,字符串是以unicode进行编码的。在unicode字符集中,汉字的编码范围为4E00(16进制) 到 9FA5(16进制) 之间(即从第19968开始的20902个字符是中文简体字符)。YUChineseSorting把这些字符的拼音首字母按照原来的顺序都存放在一个char数组中。当我们查找一个汉字的拼音首字母时,只需把这个汉字的unicode码(即char强制转换为int)减去19968,然后用这个数字作为索引去找char数组中存放的字母即可。比较野蛮的一个方法。
调用方法介绍
首先吧BMChineseSort.h及.m文件导入到项目中,只需要这两文件。
对自定义对象数组排序需要只需要使用两类个方法:
+(NSMutableArray*)IndexWithArray:(NSArray*)objectArray Key:(NSString*)key;+(NSMutableArray*)sortObjectArray:(NSArray*)objectArray Key:(NSString*)key;
第一个方法:一个参数objectArray是自定义对象数组,另一个参数key是数组里需要排序的字段名字。方法返回所有出现过的首字母,用于显示在tableview的head以及右侧索引缩写。
第二个方法:,是根据对象的某个字段值对整个数组进行排序,首先,先将字段首字母拼音相同的对象存到同一个数组里,然后把所有的数组再放到结果数组里。
获得的两个数组在tableview代理方法中的具体使用可以参考我的demo,已上传到github。
具体tableView设置
Person对象:
@interfacePerson:NSObject@property(strong,nonatomic)NSString* name;@property(assign,nonatomic)NSIntegernumber;@end
通讯录控制器viewDidLoad方法:
// array是NSArray< Person *>类型的模拟数据self.indexArray = [BMChineseSort IndexWithArray:arrayKey:@"name"];self.letterResultArr = [BMChineseSort sortObjectArray:arrayKey:@"name"];
TableView代理方法:
//section的titleHeader- (NSString*)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section {return[self.indexArray objectAtIndex:section];}//section行数-(NSInteger)numberOfSectionsInTableView:(UITableView*)tableView{return[self.indexArray count];}//每组section个数- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section{return[[self.letterResultArr objectAtIndex:section] count];}//section右侧index数组-(NSArray*)sectionIndexTitlesForTableView:(UITableView*)tableView{returnself.indexArray;}//点击右侧索引表项时调用 索引与section的对应关系- (NSInteger)tableView:(UITableView*)tableView sectionForSectionIndexTitle:(NSString*)title atIndex:(NSInteger)index{returnindex;}//返回cell- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath{UITableViewCell*cell = [tableView dequeueReusableCellWithIdentifier:@"CELL"];if(cell ==nil){ cell = [[UITableViewCellalloc] initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:@"CELL"]; }//获得对应的Person对象Person *p = [[self.letterResultArr objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; cell.textLabel.text = p.name;returncell;}
对于多音字的问题
有小伙伴
附:
网友评论