Unicode字符串索引
一、目标
在通讯录中,我们有很多联系人,需要把这些联系人进行索引。对于每一个索引项对应的若干字符串,需要对这些字符串进行排序。
需要解决两个问题:
- 如何确定某个汉字应该被哪个字符索引?
- 某个索引项对应的字符串,如何排序?
我们已经知道了问题 2 的解决方案,即 UCA + CLDR。 下面我们来解决问题 1。
二、Unicode 提供的解决方案
Unicode 指出了某个语言的索引项以及如何对某个字符进行索引。
2.1 确定语言的索引项
这个看来不是问题,肯定是 A-Z 嘛。然而并不是这样子,因为不同的语言对应的索引项不同的,同一个语言不同排序方式对应的索引项也是不同的。在common/main中,指定了语言对应的索引项。

如上图所示,中文的索引是A-Z,而“标准摩洛哥塔马塞特文 (zgh)”的索引字母是ⴰ ⴱ ⴳ ⴷ ⴹ ⴻ ⴼ ⴽ ⵀ ⵃ ⵄ ⵅ ⵇ ⵉ ⵊ ⵍ ⵎ ⵏ ⵓ ⵔ ⵕ ⵖ ⵙ ⵚ ⵛ ⵜ ⵟ ⵡ ⵢ ⵣ ⵥ。
2.2 确定某个字符对应的索引项
- 对于普通的字符来说,对应的 collation 的第一权重 (primary weight) 用来确定这个字符的索引。
这里有很多复杂的逻辑,不过对中英混排没有关系,所以先不看。 - 对于 CJK 统一表意文字有另一套规则
对于 CJK 统一表意文字,每一种排序规则(笔画、拼音、部首)都指定了索引项。下面我们通过collation/zh.xml中的内容查看规则。- 对于按照笔画排序的索引
这是繁体字的索引的规则。从下图可以看出,文字和索引项之间的关系。
 - 对于按照拼音排序的索引
这是简体字索引的规则。从下图可以看出文字和索引项之间的关系。

- 对于按照笔画排序的索引
三、iOS 对应的 API
The UILocalizedIndexedCollation class is a convenience for organizing, sorting, and localizing the data for a table view that has a section index. The table view’s data source then uses the collation object to provide the table view with input for section titles and section index titles.
UILocationdIndexedCollation 是苹果给出的API,专门用于 tableview 的排序、索引和本地化。下面我们通过一个例子来说明如何使用。
3.1 指定本地化
根据苹果文档,首先必须指定支持的地区才能正确使用这个类。
your application bundle must properly declare support for the languages you want UILocalizedIndexedCollation to support. You can add localizations to your application bundle either by adding the appropriate .lproj folders, or by specifying supported localizations in your CFBundleLocalizations key in your application's info.plist file.
文档中指出了两种方法,我们使用第二种,在info.plist文件中加入相应的key。

3.2 生成一个实例
// Get the current collation and keep a reference to it.
self.collation = [UILocalizedIndexedCollation currentCollation];
NSLog(@" section title is :%@",self.collation.sectionTitles);
当本机的语言首选项不同时,得到的sectionTitles也不同。默认语言是“简体中文”时,输出如下:
section title is :(
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
"#")
默认语言是“繁体中文(香港)”时,输出如下:
section title is :(
1 畫,
2 畫,
3 畫,
4 畫,
5 畫,
6 畫,
7 畫,
8 畫,
9 畫,
10 畫,
11 畫,
12 畫,
13 畫,
14 畫,
15 畫,
16 畫,
17 畫,
18 畫,
19 畫,
20 畫,
21 畫,
22 畫,
23 畫,
24 畫,
25 畫以上,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
"#")
3.3 把所有的字符串分配到指定的索引项中
for (NSString *str in self.allStrings) {
// Ask the collation which section number the str belongs in, based on its locale name.
NSInteger sectionNumber = [self.collation sectionForObject:str collationStringSelector:@selector(description)];
NSMutableArray *sectionStrs = newSectionsArray[sectionNumber];
// Add the str to the section.
[sectionStrs addObject:str];
}
这里的关键是下面这个函数
- (NSInteger)sectionForObject:(id)object collationStringSelector:(SEL)selector;
selector 是一个方法,返回字符串,被UILocalizedIndexedCollation实例用于判断应该把obj放到第几个section,即第几个索引项。
3.4 对每个 section 中字符进行排序
// Now that all the data's in place, each section array needs to be sorted.
for (index = 0; index < sectionTitlesCount; index++) {
NSMutableArray *strArrayForSection = newSectionsArray[index];
// If the table view or its contents were editable, you would make a mutable copy here.
NSArray *sortedStrArrayForSection = [self.collation sortedArrayFromArray:strArrayForSection collationStringSelector:@selector(description)];
// Replace the existing array with the sorted array.
newSectionsArray[index] = sortedStrArrayForSection;
}
这里的关键是下面这个函数
- (NSArray *)sortedArrayFromArray:(NSArray *)array collationStringSelector:(SEL)selector;
array 中的每一个对象执行selector方法,返回一个字符串。所有的字符串排序时候的结果就是在这个 section 中的顺序,这里排序方法加入了地区信息。当然也可以使用自定义的排序方法,只要最后得到每一个 section 中所有对象的顺序就可以了。
四、结果演示

从图中我们可以看出几个特点:
- 索引是 A-Z 再加上 #
za<左边
左边对应拼音是zuo bian,za<zuo。左边<zuo bian
首选项是汉字,汉字在前,英文在后。zuo bian<左右
因为zuo bian<zuo you,即bian<you。左右<zuobian
zuo you<zuobian。 因为空格小于任何一个字母。
五、未解决问题
其他语言是如何对应到索引项A-Z的呢?比如μ
六、参考
- UNICODE LOCALE DATA MARKUP LANGUAGE (LDML)
PART 5: COLLATION - UNICODE LOCALE DATA MARKUP LANGUAGE (LDML)
PART 2: GENERAL - UILocalizedIndexedCollation
- UITableView Fundamentals for iOS
Unicode字符串索引的更多相关文章
- Unicode 字符串排序规则(一):如何确定单个字符的顺序
一.一个具体的例子引发的问题 当今是国际化的时代,多种语言可能同时显示在屏幕上.比如一个人可能喜欢听华语歌.英文歌.韩文歌和日语歌,又比如他的联系人中有中国人.英国人.日本人.韩国人以及有英文名字的中 ...
- Python 字符串索引、切片、修改
字符串索引.切片.修改1.字符串操作(切片.修改)应用场景 a.爬虫截取网址数据 b.数据分析,语言处理(分词) c.电信号码升级 0452 8869504 ...
- Python中Unicode字符串
Python中Unicode字符串 字符串还有一个编码问题. 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特(bit)作为一个字节(byte ...
- python unicode字符串
程序开发中,不同语言文字的显示,不同字符集之间的转换非常麻烦,在python的unicode的使用中,对这点感触颇深.所以,以下总结了python中对unicode字符处理的一些理解. 程序存储.传输 ...
- UNICODE字符串与多字节字符串的转换
相互转换的两个函数的声明: 1. 多字节字符串与宽字符串的转换 int MultiByteToWideChar( UINT CodePage, // code page,一般设为 CP_ACP DWO ...
- 关于python中的unicode字符串的使用
基于python2.7中的字符串: unicode-->编码encode('utf-8')-->写入文件 读出文件-->解码decode('utf-8')-->unicode ...
- c# Unicode字符串的解码
前两天工作中遇到个奇怪的问题,一个unicode字符串(即“\uXXXX”形式)变量,调用HttpUtility.UrlDecode解码过后,还是原样,要么就是乱码状态.无奈之下只能自己写一个解码函数 ...
- Python Cookbook(第3版)中文版:15.14 传递Unicode字符串给C函数库
15.14 传递Unicode字符串给C函数库¶ 问题¶ 你要写一个扩展模块,需要将一个Python字符串传递给C的某个库函数,但是这个函数不知道该怎么处理Unicode. 解决方案¶ 这里我们需要考 ...
- Python2 处理 Unicode 字符串的规则
在 Python2 中处理 Unicode 字符串,需遵循如下规则: 1. 程序中的字符串要加前缀 u 2. 不要用 str(),而应该用 unicode() 作为字符串转换函数.不要使用 chr() ...
随机推荐
- java并发特性:原子性、可见性、有序性
要想并发程序正确地执行,必须要保证原子性.可见性以及有序性.只要有一个没有被保证,就有可能会导致程序运行不正确. 1.原子性(Atomicity) 原子性是指在一个操作中就是cpu不可以在中途暂停然后 ...
- 基于webpack的Vue.js开发环境快速搭建
1. 安装node node下载地址 2. 安装淘宝 NPM npm 是node.js 的包管理工具. 镜像命令地址 #命令行: npm install -g cnpm 3. 安装vue # 全局安装 ...
- 在cmd中显示mysql -uroot-proot 不是命令
这个代码的意思是打开mysql,用户名为root,密码也是root 解决办法:方法一:首先要进入mysql的bin目录下,再执行. 密码错了,重新输入密码,没有密码嘛
- Java常用的输出调试技巧
--------siwuxie095 Eclipse 开发中常用的输出调试技巧: 先在左侧的 Package Explorer,右键->New->J ...
- SpringCloud之自动化配置-config
编程开发的时候有没有觉得很多配置文件需要维护,比如,修改了数据库连接,所有用到该数据库的服务配置都得替换,是不是超级的麻烦呢 下面,给大家介绍一下Spring提供的配置自动化组件-spring clo ...
- 解决Error running 'index.jsp : Address localhost:1099 is already in use的方法
晚上在idea中 启动服务器一次后 正常运行,但是改了注解配置后 报错,报错为Error running 'index.jsp : Address localhost:1099 is alread ...
- Java线程死锁查看分析方法
如何查看是否有Java线程死锁?下面介绍两种方法. 一.Jconsole Jconsole是JDK自带的图形化界面工具,使用JDK给我们的的工具JConsole,可以通过打开cmd然后输 ...
- UVa 1616 Caravan Robbers (二分+贪心)
题意:给定 n 个区间,然后把它们变成等长的,并且不相交,问最大长度. 析:首先是二分最大长度,这个地方精度卡的太厉害了,都卡到1e-9了,平时一般的1e-8就行,二分后判断是不是满足不相交,找出最长 ...
- SSM的项目框架
- Alpha冲刺 - (6/10)
Part.1 开篇 队名:彳艮彳亍团队 组长博客:戳我进入 作业博客:班级博客本次作业的链接 Part.2 成员汇报 组员1(组长)柯奇豪 过去两天完成了哪些任务 基于ssm框架的前后端交互测试,结合 ...