按中文拼音排序的小技巧

说到按中文拼音排序,很多人就想到了通过『拼音字典』的相关库来实现。随便在github搜索一下 拼音 发现库确实挺多的,不过实现成本都有点高。再搜索 拼音排序 还真有,我简单的看了下,实现方式五花八门。

今天分享一个按拼音排序的小技巧,与语言无关,但是用PHP实现最简单就用PHP做演示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$province_arr = ['山东','山西','安徽','北京','福建','甘肃','广东','贵州'];

usort($province_arr,function($a,$b){
$a = iconv('UTF-8', 'GBK//IGNORE', $a);
$b = iconv('UTF-8', 'GBK//IGNORE', $b);
return $a>$b?1:-1;
});
print_r($province_arr);
/**结果如下
Array
(
[0] => 安徽
[1] => 北京
[2] => 福建
[3] => 甘肃
[4] => 广东
[5] => 贵州
[6] => 山东
[7] => 山西
)
**/

不算闭包函数的话一行代码就实现了『将汉字用拼音排序』的功能,当然这段代码有一点缺陷就是数组中的每一行数据都执行了两次iconv() 函数,这是可以优化的。另一点就是扩展性不足,遇到英文开头的字符串时需要做特殊处理。除此之外相当给力的一种方法,下面说说他排序的原理。

GBK编码,是对GB2312编码的扩展,因此完全兼容GB2312-80标准。GBK编码依然采用双字节编码方案,其编码范围:8140-FEFE,剔除xx7F码位,共23940个码位。共收录汉字和图形符号21886个,其中汉字(包括部首和构件)21003个,图形符号883个。GBK编码支持国际标准ISO/IEC10646-1和国家标准GB13000-1中的全部中日韩汉字,并包含了BIG5编码中的所有汉字。GBK编码方案于1995年12月15日正式发布,这一版的GBK规范为1.0版。更新介绍

上面一段是GBK编码的简介,要是认真看GBK编码的介绍的话会发现一个很有意思的事情。

GBK编码汉字区包括:

a. GB 2312 汉字区。即 GBK/2: B0A1-F7FE。收录 GB 2312 汉字 6763 个,按原顺序排列

b. GB 13000.1 扩充汉字区。包括:

  1. GBK/3: 8140-A0FE。收录 GB 13000.1 中的 CJK 汉字 6080 个。
  1. GBK/4: AA40-FEA0。收录 CJK 汉字和增补的汉字 8160 个。CJK 汉字在前,按 UCS 代码大小排列;增补的汉字(包括部首和构件)在后,按《康熙字典》的页码/字位排列

我们发现GBK编码的两次扩充都是基于拼音做的编码排序,所以整个GBK汉字区的中文符号都自带拼音权重。所以通过这个权重我们能轻松的实现『将汉字用拼音排序』功能。

另外GBK编码与编程语言无关,我们通过Java,JS,Golang都能很轻松的实现拼音排序功能。