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

avatar
作者
筋斗云
阅读量:0

在这里插入图片描述

文章目录


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

一、前言

  • 在程序中,我们经常需要对一些列表数据进行排序。排序方法有很多种,可以使用内置方法 sort,也可以通过一些排序算法来实现排序效果,如快速排序,选择排序,冒泡排序等。但无论使用哪种排序方法,总归需要先确定好排序规则。
  • 前端日常使用的排序规则主要有:编码排序字典排序
  • 在常规程序中,默认的排序规则大部分都是编码排序,也就是所谓的 Unicode编码。比如在 js 中,数组的 sort 方法,默认排序规则就是编码排序。

二、编码排序

  • 在计算机中,任何符号都有一个编码,将所有的编码收录起来,就是Unicode编码,也叫万国码、统一码。
  • Unicode编码并不会被我们直观的看到,在js中可以通过str.codePointAt()方法进行转换。
console.log( '中'.codePointAt() );		// 20013 console.log( '文'.codePointAt() );		// 25991 console.log( 'a'.codePointAt() );			// 97 console.log( 'A'.codePointAt() );			// 65 
  • 当然也可以将编码再转回字符,只要利用String.fromCodePoint(编码值)方法即可。
console.log( String.fromCodePoint(20013) );		// 中 console.log( String.fromCodePoint(25991) );		// 文 
  • 在Unicode编码中,字母'a'的编码为97,字母'A'的编码为65,所以如果使用sort进行升序排列,字符'A'会在'a'之前
const arr = ['a', 'A']; arr.sort(); console.log( arr );		// ['A', 'a'] 
  • 这就是编码排序。
  • 哪怕并不是做排序操作,只是判断大小,js默认也会按照编码大小进行比较
console.log('a' > 'A');		// true 
  • 中文在进行排序时,默认也是按照编码进行排序
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。
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的回调函数,即可实现。
const arr = ['张三', '李四', '王二', '赵五', '李美丽', '王漂亮', '张英俊'];  // 升序 arr.sort( (a, b) => a.localeCompare(b) ); console.log( arr ); // ['李美丽', '李四', '王二', '王漂亮', '张三', '张英俊', '赵五']  // 降序 arr.sort( (a, b) => b.localeCompare(a) ); console.log( arr ); // ['赵五', '张英俊', '张三', '王漂亮', '王二', '李四', '李美丽'] 

四、拼音库

  • 如果使用localeCompare方法进行排序,还没有满足你的需求,你需要直观的看到每个中文的拼音,这里推荐一个强大的拼音库:PinyinJS
  • 简单演示一下基本用法:
<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文档
  • 此时在一些需要基于拼音进行的操作就可以继续推进了。

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!