文章目录
注:本文内容为排序规则的讨论,不是排序算法
一、前言
- 在程序中,我们经常需要对一些列表数据进行排序。排序方法有很多种,可以使用内置方法 sort,也可以通过一些排序算法来实现排序效果,如快速排序,选择排序,冒泡排序等。但无论使用哪种排序方法,总归需要先确定好排序规则。
- 前端日常使用的排序规则主要有:编码排序 、字典排序。
- 在常规程序中,默认的排序规则大部分都是编码排序,也就是所谓的 Unicode编码。比如在 js 中,数组的 sort 方法,默认排序规则就是编码排序。
二、编码排序
- 在计算机中,任何符号都有一个编码,将所有的编码收录起来,就是Unicode编码,也叫万国码、统一码。
- Unicode编码并不会被我们直观的看到,在js中可以通过
str.codePointAt()
方法进行转换。
javascript
console.log( '中'.codePointAt() ); // 20013
console.log( '文'.codePointAt() ); // 25991
console.log( 'a'.codePointAt() ); // 97
console.log( 'A'.codePointAt() ); // 65
- 当然也可以将编码再转回字符,只要利用
String.fromCodePoint(编码值)
方法即可。
javascript
console.log( String.fromCodePoint(20013) ); // 中
console.log( String.fromCodePoint(25991) ); // 文
- 在Unicode编码中,字母
'a'
的编码为97
,字母'A'
的编码为65
,所以如果使用sort
进行升序排列,字符'A'
会在'a'
之前
javascript
const arr = ['a', 'A'];
arr.sort();
console.log( arr ); // ['A', 'a']
- 这就是编码排序。
- 哪怕并不是做排序操作,只是判断大小,js默认也会按照编码大小进行比较
javascript
console.log('a' > 'A'); // true
- 中文在进行排序时,默认也是按照编码进行排序
javascript
console.log( "中" > "文" ); // false
console.log( "中" < "文" ); // true
const arr = ['文', '中'];
arr.sort();
console.log( arr ); // ['中', '文']
- 但在日常场景中,中文排序最常见的规则是拼音排序,也就是字典顺序
- 当然,网上也有许多的拼音库,用于将中文拆分成拼音,不过用起来比较麻烦。
- JS中已经提供一个API,用于快速得到这个字典顺序。
三、字典排序
- 所谓字典排序,可以简单的理解成每个字符(尤其是中文)在字典中的顺序(按照拼音排序)。
- 字典排序,也是按照字符的编码进行排序,只不过它在比较字符时,可以根据不同的编码方式产生不同的排序结果。例如,在
UTF-8
编码中,中文字符的排序与拼音顺序有关,而在GBK
编码中则与拼音顺序无关。 - 在JS中可以通过
localeCompare
方法来得到两个字符在指定字符编码中的顺序。 localeCompare()
方法返回一个数字,表示参考字符串在排序顺序中是在给定字符串之前、之后还是与之相同。
javascript
console.log( '李'.localeCompare('王') ); // -1
// 李 ,在 王 之前
// 李:li
// 赵:wang
// l 在 w 之前
console.log( '赵'.localeCompare('王') ); // 1
// 赵 ,在 王 之后
// 赵:zhao
// 王:wang
// z 在 w 之后
console.log( '钱'.localeCompare('瞿') ); // -1
// 钱 ,在 瞿 之前
// 钱:qian
// 瞿:qu
// q 相同,比较 i 和 u , i 在 u 之前
- 那如何利用
localeCompare
方法对中文进行排序呢, - 只需要配合sort的回调函数,即可实现。
javascript
const arr = ['张三', '李四', '王二', '赵五', '李美丽', '王漂亮', '张英俊'];
// 升序
arr.sort( (a, b) => a.localeCompare(b) );
console.log( arr );
// ['李美丽', '李四', '王二', '王漂亮', '张三', '张英俊', '赵五']
// 降序
arr.sort( (a, b) => b.localeCompare(a) );
console.log( arr );
// ['赵五', '张英俊', '张三', '王漂亮', '王二', '李四', '李美丽']
四、拼音库
- 如果使用
localeCompare
方法进行排序,还没有满足你的需求,你需要直观的看到每个中文的拼音,这里推荐一个强大的拼音库:PinyinJS- 文档:PinyinJS文档
- 简单演示一下基本用法:
html
<script src="https://raw.gitcode.com/liuxianan/pinyinjs/raw/master/dict/pinyin_dict_notone.js"></script>
<script src="https://raw.gitcode.com/liuxianan/pinyinjs/raw/master/pinyinUtil.js"></script>
<script>
console.log( pinyinUtil.getPinyin("中国") ); // 'zhong guo'
console.log( pinyinUtil.getHanzi("zhong") ); // 中重种众终钟忠仲衷肿踵冢盅蚣忪锺舯螽夂
</script>
- 可以在中文和拼音之间进行转换。
- 需要注意的是,在将拼音转成中文时,会得到该拼音所有的中文。
- 因为拼音库一般比较大,我们并不推荐在客户端进行拼音转换操作,应尽可能的在服务器进行,然后通过接口将转换后的拼音传给前端
- PinyinJS库还提供了首字母、声调,以及多音字的处理方案,详情请查阅PinyinJS文档
- 此时在一些需要基于拼音进行的操作就可以继续推进了。