BMChineseSort
是一个为模型、字典、字符串数组根据特定中文属性基于tableview分组优化的工具类,基于异步、多线程降低排序时间。对于多音字的问题,开放了一个映射属性,可手动修改个别多音字或你想要的映射关系。
普通自定义的模型对象
//Person模型
@interface Person : NSObject
@property (strong , nonatomic) NSString * name;
@property (assign , nonatomic) NSInteger number;
@end
使用sortWithArray方法进行排序
NSMutableArray<Person*> *dataArr;//数据源
NSMutableArray *firstLetterArray;//排序后的出现过的拼音首字母数组
NSMutableArray *sortedModelArr;//排序好的结果数组
[BMChineseSort sortWithArray:dataArr key:@"name" finish:^(bool isSuccess, NSMutableArray *unGroupArr, NSMutableArray *sectionTitleArr, NSMutableArray<NSMutableArray *> *sortedObjArr) {
if (isSuccess) {
self.firstLetterArray = sectionTitleArr;
self.sortedModelArr = sortedObjArr;
[_tableView reloadData];
}
}];
使用排序结果
//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{
return self.indexArray;
}
//点击右侧索引表项时调用 索引与section的对应关系
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index{
return index;
}
//返回cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CELL"];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CELL"];
}
//获得对应的Person对象<替换为你自己的model对象>
Person *p = [[self.letterResultArr objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
cell.textLabel.text = p.name;
return cell;
}
使用方法与模型排序相同,注意 key = nil,否则排序失败。
NSMutableArray * provinceArr = @[@"北京",@"河南",@"重庆",@"沈阳",@"长春",@"abc",];
//字符串数组 key 传nil 即可
[BMChineseSort sortWithArray:provinceArr key:nil finish:^(bool isSuccess, NSMutableArray *unGroupArr, NSMutableArray *sectionTitleArr, NSMutableArray<NSMutableArray *> *sortedObjArr){
// sortedObjArr是NSMutableArray<NSMutableArray *<NSString*>>类型
}];
在回调方法中 拿到 unGroupArr
即可 ,模型和字符串排序都支持
通过 BMChineseSortSetting.share
来进行设置
属性 | 默认值 | 描述 |
---|---|---|
sortMode | 2 | 排序所用方法,1 使用CFStringTransform,2使用汉字码表,详见:文字转拼音方法选择 |
logEable | YES | 是否开启打印,YES=开启 |
specialCharSectionTitle | “#” | 特殊字符最后单独分组所用的 分组名称 |
specialCharPositionIsFront | YES | 特殊字符所在位置 YES = 开头,NO = 结尾 |
ignoreModelWithPrefix | “” | 剔除 特定字符开头的对象,详见:剔除特定字符开头的元素 |
polyphoneMapping | 包含部分常用多音字 | 常用多音字 手动映射,详见:多音字映射 |
两种方法都是基于多线程异步操作后进行优化了。
-
sortMode=1 使用系统CFStringTransform 方法转换,比较耗时
-
sortMode=2 使用汉字码表对应的首字母码表,通过编码顺序查找,比较快。(码表来源于网络,没有验证过,但基本没什么问题)如遇到多音字或者可能错误的拼音映射,可以码表配合polyphoneMapping手动修改错误的映射
BMChineseSortSetting.share.sortMode = 1
如果想过滤 某些字符开头的元素,不出现在最终结果集中,使用 ignoreModelWithPrefix
,不要与 specialCharSectionTitle 冲突。下面例子中剔除了所有元素中对应key的值是数字
开头的元素
BMChineseSortSetting.share.ignoreModelWithPrefix = @"0123456789"
实际使用中如果遇到想手动映射拼音的 可以使用到polyphoneMapping
完成映射,由于多音字在本地中是无法动态解决的,如果不是通过后台获取的拼音,则只能通过手动过滤的方法了。
如果你觉得常用的,可以在issue中提出来,我更新在默认值中。
- 使用格式: {"匹配的文字":"对应的首字母(大写)"}
//使用时不需要添加,直接赋值即可,不会覆盖上一次的值
BMChineseSortSetting.share.polyphoneMapping = @{@"长安":@"CA"};
BMChineseSortSetting.share.polyphoneMapping = @{@"长":@"C"};//所有长 都映射为chang(C)
BMChineseSortSetting.share.polyphoneMapping = @{@"厦门":@"XM",@"重庆":@"CQ"};
默认已添加的常用的多音字映射:
@{ @"重庆":@"CQ",
@"厦门":@"XM",
@"长":@"C",
@"沈":@"S",
}
设置中添加 specialCharPositionIsFront, 可设置特殊字符所在位置
添加未分组的结果集回调,修改demo
1.合并IndexWithArray:
和sortObjectArray
方法,减少对数据的多次遍历造成的时间浪费,
2.同时添加将排序转入后台多线程,使用block回调拿到数据。
3.将模型与字符串排序合并为一个方法,使用通过key区分。