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文档
  • 此时在一些需要基于拼音进行的操作就可以继续推进了。
相关推荐
微学AI43 分钟前
一根针指向所有方向:挂谷猜想对 LLM Agent 技能-记忆架构的启示
开发语言·人工智能·架构·挂谷猜想
豆瓣鸡1 小时前
算法日记 - Day3
java·开发语言·算法
夏殇之殁2 小时前
包中创建自定义列表项。 . 使用自定义列表项进行数据绑定 . 将天气预报数据保存到本地内存表,通过LiveBindings进行显示。 ...
服务器·前端·javascript
韭菜炒鸡肝天2 小时前
VTK开发笔记(一):VTK介绍,Qt..+VSx+VTK.编译
开发语言·笔记·qt
Aaron - Wistron3 小时前
Web API C# (Furion版)带 单元测试
开发语言·后端·c#
新中地GIS开发老师3 小时前
WebGIS开发学生作品|低空航天管理与航线规划系统
前端·javascript·webgis·三维gis开发
丙氨酸長鏈3 小时前
Web前端入门第 问:JavaScript 一个简单的 IndexedDB 数据库入门示例
前端·javascript·数据库
Dxy12393102164 小时前
Python项目打包成EXE完整教程(PyInstaller实战避坑)
开发语言·python
0566464 小时前
Python康复训练——常用标准库
开发语言·python·学习
骊城英雄4 小时前
基于C#+avalonia ui实现的跨平台点胶机灌胶监控控制上位机软件
开发语言·ui·c#