本地化下按首字母分组排序的神器——UILocalizedIndexedCollation

  最近在整一个很简单的通讯录相关的项目,通讯录当然就少不了按首字母或者汉字拼音首字母分组排序索引。因为按照我一贯的的做法,都是想要做成更通用的、支持本地化的,所以这就纠结了,世界各地的语言啊我去,我顶多也就认识中文和英语,这就不能用以前的那些比如把汉字转成拼音再排序的方法了,效率不高不说,对其他国家的本地化更是行不通。一个偶然的机会,我才发现SDK里已经提供了一个实现此功能的神器——UILocalizedIndexedCollation。

  首先提一下,UILocalizedIndexedCollation的分组排序是建立在对对象的操作上的。下边我会举个栗子讲解一下。首先已知有一个Person类:

1 @interface Person : NSObject
2 @property(nonatomic, strong) NSString *name;
3 @end

然后初始化一些对象存入一个数组(注:为了后续说明方便,我直接拿name的值来表示Person类的对象,实际编码中是要用对象!如下列<林丹>表示p.name = @"林丹"的Person类对象p)

1 NSArray *srcArray = @[<林荣>, <林丹>, <周董>, <周树人>, <周杰伦>, <阿华>];

先将UILocalizedIndexedCollation初始化,

1 UILocalizedIndexedCollation *collation = [UILocalizedIndexedCollation currentCollation];

可以看出来这是一个单例,它会根据不同国家的语言初始化出不同的结果。如中文和英文的得到的就是A~Z和#,日语的就是A~Z,あ, か, さ, た, な, は, ま, や, ら, わ和#。下边我就以最熟悉的中文环境为例,直接上代码了,注意看注释部分的讲解

 1 //得出collation索引的数量,这里是27个(26个字母和1个#)
 2 NSInteger sectionTitlesCount = [[collation sectionTitles] count];
 3
 4 //初始化一个数组newSectionsArray用来存放最终的数据,我们最终要得到的数据模型应该形如@[@[以A开头的数据数组], @[以B开头的数据数组], @[以C开头的数据数组], ... @[以#(其它)开头的数据数组]]
 5
 6 NSMutableArray *newSectionsArray = [[NSMutableArray alloc] initWithCapacity:sectionTitlesCount];
 7
 8 //初始化27个空数组加入newSectionsArray
 9 for (NSInteger index = 0; index < sectionTitlesCount; index++) {
10     NSMutableArray *array = [[NSMutableArray alloc] init];
11     [newSectionsArray addObject:array];
12 }
13
14 //将每个人按name分到某个section下
15
16 for (Person *p in srcArray) {
17   //获取name属性的值所在的位置,比如"林丹",首字母是L,在A~Z中排第11(第一位是0),sectionNumber就为11
18     NSInteger sectionNumber = [collation sectionForObject:p collationStringSelector:@selector(name)];
19   //把name为“林丹”的p加入newSectionsArray中的第11个数组中去
20     NSMutableArray *sectionNames = newSectionsArray[sectionNumber];
21     [sectionNames addObject:p];
22 }
23
24 //对每个section中的数组按照name属性排序
25 for (NSIntger index = 0; index < sectionTitlesCount; index++) {
26     NSMutableArray *personArrayForSection = newSectionsArray[index];
27     NSArray *sortedPersonArrayForSection = [collation sortedArrayFromArray:personArrayForSection collationStringSelector:@selector(name)];
28     newSectionsArray[index] = sortedPersonArrayForSection;
29 }

最终把newSectionsArray应该形如@[@[<阿华>], @[], @[], ... @[<林丹>, <林荣>], ... @[], @[<周董>, <周杰伦>, <周树人>]]

后续工作就是把这个数组作为数据源与UITableView通过tableView的Delegate关联起来了,部分如下,在此不再赘述

 1 - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
 2     return [collation sectionTitles][section];
 3 }
 4
 5 - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
 6     return [collation sectionIndexTitles];
 7 }
 8
 9 - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
10     return [collation sectionForSectionIndexTitleAtIndex:index];
11 }

  不过呢,使用这个UILocalizedIndexedCollation有一个缺点就是不能区分姓氏中的多音字,比如“曾”会被分到"C"组去,不知道大家有没有基于此的好方法在下边回复。下边是苹果官方示例,其中第3个是关于UILocalizedIndexedCollation的,可以下载下来学习一下http://developer.apple.com/library/ios/samplecode/TableViewSuite/Introduction/Intro.html

时间: 2024-08-02 10:53:14

本地化下按首字母分组排序的神器——UILocalizedIndexedCollation的相关文章

按首字母分组排序数组

1 2 3 // 按首字母分组排序数组 4 5 -(NSMutableArray *)sortObjectsAccordingToInitialWith:(NSArray *)arr { 6 7 8 9 // 初始化UILocalizedIndexedCollation 10 11 UILocalizedIndexedCollation *collation = [UILocalizedIndexedCollation currentCollation]; 12 13 14 15 //得出col

sql中如何按某字段值的首字母分组?

sql中如何按某字段值的首字母分组?如一字段有值: x001 x003 p005 y0093 分组结果应为.X=2,p=1,y=1 ------解决方案--------------------如一字段有值: x001 x003 p005 y0093 分组结果应为.X=2,p=1,y=1 select left(col,1) , count(*) from tb group by left(col,1)

字符串按首字母分组并ToDictionary的实现

这是携程(深圳).net开发笔试的一道题目,要求实现字符串按首字母分组并ToDictionary输出,当时没有做出来,后面研究了一下,现在将这道题的几种实现方式记录下来. 首先初始化数据源,是一个List<string>对象.如下代码. //数据源 List<string> list = new List<string> { "Beijing", "Shanghai", "Tianjin", "Cho

关于java中实现在oracle数据库中实现对中文首字母进行排序的解决方案

首先介绍Oracle 9i新增加的一个系统自带的排序函数 1.按首字母排序 在oracle9i中新增了按照拼音.部首.笔画排序功能.设置NLS_SORT值     SCHINESE_RADICAL_M   按照部首(第一顺序).笔划(第二顺序)排序     SCHINESE_STROKE_M   按照笔划(第一顺序).部首(第二顺序)排序     SCHINESE_PINYIN_M   按照拼音排序 oracle9i中新增了按照拼音.部首.笔画排序功能 用法示例: Java代码   拼音 SEL

Java -------- 首字母相关排序总结

Java 字符串数组首字母排序 字符串数组按首字母排序:(区分大小写) String[] strings = new String[]{"ba","aa","CC","Ba","DD","ee","dd"}; Arrays.sort(strings); for (int i = 0; i < strings.length; i++) { System.out.p

mysql 中将汉字按照首字母排序

因为数据库中可以设定表的编码格式,不同编码格式下,中文的排序有区别,下面分别介绍常用编码下的排序方法. 1.如果数据表的某字段的字符编码是 utf8_general_ci,排序写法: ORDER BY CONVERT(表别名.字段名 USING gbk) COLLATE gbk_chinese_ci ASC; 例子 SELECT * FROM mg_clinic mc ORDER BY CONVERT(mc.`CLNAME` USING gbk) COLLATE gbk_chinese_ci A

js中文首字母排序(一)

sort()localeCompare() sort()使用,sort()函数会对使用的数组对象进行排序,排序规则安装字符编码顺序排序, 如:(无法直接比较中文) var arr = new Array(6); arr[0] = "23" arr[1] = "1" arr[2] = "8" arr[3] = "25" arr[4] = "1000" arr[5] = "1" arr.so

IOS数组按中文关键字以字母序排序

本文转载至 http://blog.csdn.net/xunyn/article/details/7882087 iosobjective cuser框架通讯 IOS项目中会用到对通讯录的联系人或是会员按姓名为关键字排序,因为NSArray并不直接支持对汉字的排序,这就要通过将汉字转换成拼音完成按A~Z的排序,这看起来是个头疼的问题,因为牵扯到汉字转为拼音,kmyhy给出一个较易实现的方法,获取汉字的首字的首字母,如将“王”变成“W”,完整文章(传送门). 其中他通过pinyinFirstLet

C# 获取汉字拼音首字母

最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷 学无止境,精益求精   本节探讨C#获取汉字拼音首字母的方法: 代码类东西,直接上代码: /// <summary> /// 在指定的字符串列表CnStr中检索符合拼音索引字符串 /// </summary> /// <param name="CnStr">汉字字符串</param> /// <returns&