JavaScript字符排序规则(编码排序、字典排序)

文章目录

注:本文内容为排序规则的讨论,不是排序算法

一、前言

  • 在程序中,我们经常需要对一些列表数据进行排序。排序方法有很多种,可以使用内置方法 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()方法返回一个数字,表示参考字符串在排序顺序中是在给定字符串之前、之后还是与之相同。
    • 完整语法:referenceStr.localeCompare(compareString, locales, options)
      • 参数:
        • compareString:用于和referenceStr比较的字符串。
        • locales:可选,表示缩写语言代码(BCP 47 language tag)的字符串,或由此类字符串组成的数组。点击参考
        • options:可选,一个调整输出格式的对象,点击参考
      • 返回值:
        • 如果引用字符串referenceStr存在于比较字符串compareString之前则为负数;如果引用字符串存在于比较字符串之后则为正数;相等的时候返回 0。
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
  • 简单演示一下基本用法:
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文档
  • 此时在一些需要基于拼音进行的操作就可以继续推进了。
相关推荐
逊嘘2 分钟前
【Java语言】抽象类与接口
java·开发语言·jvm
Half-up5 分钟前
C语言心型代码解析
c语言·开发语言
别拿曾经看以后~12 分钟前
【el-form】记一例好用的el-input输入框回车调接口和el-button按钮防重点击
javascript·vue.js·elementui
川石课堂软件测试17 分钟前
性能测试|docker容器下搭建JMeter+Grafana+Influxdb监控可视化平台
运维·javascript·深度学习·jmeter·docker·容器·grafana
Source.Liu26 分钟前
【用Rust写CAD】第二章 第四节 函数
开发语言·rust
monkey_meng26 分钟前
【Rust中的迭代器】
开发语言·后端·rust
余衫马29 分钟前
Rust-Trait 特征编程
开发语言·后端·rust
JerryXZR32 分钟前
前端开发中ES6的技术细节二
前端·javascript·es6
monkey_meng33 分钟前
【Rust中多线程同步机制】
开发语言·redis·后端·rust
Jacob程序员35 分钟前
java导出word文件(手绘)
java·开发语言·word