一、目标

在通讯录中,我们有很多联系人,需要把这些联系人进行索引。对于每一个索引项对应的若干字符串,需要对这些字符串进行排序。
需要解决两个问题:

  1. 如何确定某个汉字应该被哪个字符索引?
  2. 某个索引项对应的字符串,如何排序?

我们已经知道了问题 2 的解决方案,即 UCA + CLDR。 下面我们来解决问题 1。

二、Unicode 提供的解决方案

Unicode 指出了某个语言的索引项以及如何对某个字符进行索引。

2.1 确定语言的索引项

这个看来不是问题,肯定是 A-Z 嘛。然而并不是这样子,因为不同的语言对应的索引项不同的,同一个语言不同排序方式对应的索引项也是不同的。在common/main中,指定了语言对应的索引项。

如上图所示,中文的索引是A-Z,而“标准摩洛哥塔马塞特文 (zgh)”的索引字母是ⴰ ⴱ ⴳ ⴷ ⴹ ⴻ ⴼ ⴽ ⵀ ⵃ ⵄ ⵅ ⵇ ⵉ ⵊ ⵍ ⵎ ⵏ ⵓ ⵔ ⵕ ⵖ ⵙ ⵚ ⵛ ⵜ ⵟ ⵡ ⵢ ⵣ ⵥ

2.2 确定某个字符对应的索引项

  1. 对于普通的字符来说,对应的 collation 的第一权重 (primary weight) 用来确定这个字符的索引。
    这里有很多复杂的逻辑,不过对中英混排没有关系,所以先不看。
  2. 对于 CJK 统一表意文字有另一套规则
    对于 CJK 统一表意文字,每一种排序规则(笔画、拼音、部首)都指定了索引项。下面我们通过collation/zh.xml中的内容查看规则。

    1. 对于按照笔画排序的索引
      这是繁体字的索引的规则。从下图可以看出,文字和索引项之间的关系。
    2. 对于按照拼音排序的索引
      这是简体字索引的规则。从下图可以看出文字和索引项之间的关系。

三、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 中所有对象的顺序就可以了。

四、结果演示


从图中我们可以看出几个特点:

  1. 索引是 A-Z 再加上 #
  2. za < 左边
    左边 对应拼音是zuo bianza < zuo
  3. 左边 <zuo bian
    首选项是汉字,汉字在前,英文在后。
  4. zuo bian < 左右
    因为zuo bian < zuo you,即bian < you
  5. 左右 < zuobian
    zuo you < zuobian。 因为空格小于任何一个字母。

五、未解决问题

其他语言是如何对应到索引项A-Z的呢?比如μ

六、参考

  1. UNICODE LOCALE DATA MARKUP LANGUAGE (LDML)
    PART 5: COLLATION
  2. UNICODE LOCALE DATA MARKUP LANGUAGE (LDML)
    PART 2: GENERAL
  3. UILocalizedIndexedCollation
  4. UITableView Fundamentals for iOS

Unicode字符串索引的更多相关文章

  1. Unicode 字符串排序规则(一):如何确定单个字符的顺序

    一.一个具体的例子引发的问题 当今是国际化的时代,多种语言可能同时显示在屏幕上.比如一个人可能喜欢听华语歌.英文歌.韩文歌和日语歌,又比如他的联系人中有中国人.英国人.日本人.韩国人以及有英文名字的中 ...

  2. Python 字符串索引、切片、修改

    字符串索引.切片.修改1.字符串操作(切片.修改)应用场景    a.爬虫截取网址数据    b.数据分析,语言处理(分词)    c.电信号码升级           0452 8869504   ...

  3. Python中Unicode字符串

    Python中Unicode字符串 字符串还有一个编码问题. 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特(bit)作为一个字节(byte ...

  4. python unicode字符串

    程序开发中,不同语言文字的显示,不同字符集之间的转换非常麻烦,在python的unicode的使用中,对这点感触颇深.所以,以下总结了python中对unicode字符处理的一些理解. 程序存储.传输 ...

  5. UNICODE字符串与多字节字符串的转换

    相互转换的两个函数的声明: 1. 多字节字符串与宽字符串的转换 int MultiByteToWideChar( UINT CodePage, // code page,一般设为 CP_ACP DWO ...

  6. 关于python中的unicode字符串的使用

    基于python2.7中的字符串: unicode-->编码encode('utf-8')-->写入文件 读出文件-->解码decode('utf-8')-->unicode ...

  7. c# Unicode字符串的解码

    前两天工作中遇到个奇怪的问题,一个unicode字符串(即“\uXXXX”形式)变量,调用HttpUtility.UrlDecode解码过后,还是原样,要么就是乱码状态.无奈之下只能自己写一个解码函数 ...

  8. Python Cookbook(第3版)中文版:15.14 传递Unicode字符串给C函数库

    15.14 传递Unicode字符串给C函数库¶ 问题¶ 你要写一个扩展模块,需要将一个Python字符串传递给C的某个库函数,但是这个函数不知道该怎么处理Unicode. 解决方案¶ 这里我们需要考 ...

  9. Python2 处理 Unicode 字符串的规则

    在 Python2 中处理 Unicode 字符串,需遵循如下规则: 1. 程序中的字符串要加前缀 u 2. 不要用 str(),而应该用 unicode() 作为字符串转换函数.不要使用 chr() ...

随机推荐

  1. 2015年传智播客JavaEE 第168期就业班视频教程day38-SSH综合案例-1

    为什么需要划分模块呢?因为需要知道一些大致的功能,其次呢需要知道我们后台需不需要对它进行维护.如果需要呢那它肯定是一个单独的模块, 1.1    网上商城需求分析: 1.1.1 前台:用户模块 注册: ...

  2. 0. ACM系列算法

    0.1 数学 0.1.1 概率 http://www.cnblogs.com/jiu0821/tag/%E6%A6%82%E7%8E%87/ 0.1.2 代数 0.1.2.1 Polya 0.1.2. ...

  3. 二叉树翻转 · binary tree flipping

    [抄题]: 给定一个二叉树,其中所有右节点要么是具有兄弟节点的叶节点(有一个共享相同父节点的左节点)或空白,将其倒置并将其转换为树,其中原来的右节点变为左叶子节点.返回新的根节点. 您在真实的面试中是 ...

  4. Resolving multicopy duplications de novo using polyploid phasing 用多倍体相位法解决多拷贝复制的新问题

    抽象.虽然单分子测序系统的兴起已经实现组装复杂地区的能力空前提高在基因组中,基因组中的长节段重复仍然是装配中具有挑战性的前沿. 分段重复同时具有丰富的基因并且倾向于大的结构重排,使得它们的序列的分辨率 ...

  5. wcf服务编程(第3版)文摘

    第1章 wcf基础 什么是wcf: System.ServiceModel.dll 服务 服务的执行边界: proxy 地址:http/https,tcp,ipc,peer newwork,msmq, ...

  6. asp.net 4高级程序设计( 第4版)文摘

    第一部分 核心概念 第1章 asp.net 简介 第2章 visual studio 第3章 Web窗体 3.2 web窗体处理阶段 页面框架初始化(page.init),用户代码初始化(page.l ...

  7. java类的泛型DAO

    @Transactional public abstract class DAOSupport<T> implements DAO<T> { protected Class&l ...

  8. nodename nor servname provided, or not known

    mac来使用redis然后产生上述错误,据说是用户名的问题 解决: 打开终端: cat /private/etc/hosts sudo vi /private/etc/hosts 将错误的那个名字加入 ...

  9. BZOJ 2002 Bounce 弹飞绵羊 (分块或动态树)

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 13768  Solved: 6989[Subm ...

  10. visualstudio 2013 mysql entityframework :实体模型无法添加,闪退

    发现电脑中安装的mysql-connector-net,版本为6.9.8 1.卸载此版本 2.重新安装mysql-connector-net 6.8.3 3.注意web.config中版本 4.注意项 ...