需求的产生

今天在需求评审的过程中,遇见一个排序问题

地区的拼音按照a-z的顺序进行排序。

研究了一下,主要有下面三种做法。

1,使用 String.prototype.localeCompare()

2,new Intl.Collator()

3,使用第3方库 pinyin

下面我们来详细的介绍一下3种实现方法。

localeCompare 的介绍

localeCompare:用于比较两个字符串,并返回一个数字,表示哪个字符串应该排在前面。

语法:string.localeCompare(compareString, locales, options)

localeCompare 的第2个参数说明:

默认情况下,中文会按 Unicode 编码排序。

添加 'zh-Hans-CN' 后自动启用拼音顺序。

'zh-CN':zh-CN 是地区导向的标签(中国大陆中文)

'zh-Hans-CN': zh-Hans-CN 是脚本+地区导向的标签(中国大陆简体中文)

需要精确控制时选zh-Hans-CN,追求通用兼容时选zh-CN

localeCompare 的第3个参数options说明:(可选):一个对象,指定比较的行为。

ignorePunctuation:true, 忽略标点符号。

caseFirst:控制大小写排序顺序。'upper':大写字母优先, 'lower':小写字母优先。

numeric:设为true时,按数字顺序比较字符串。如“苹果10”排在“苹果2”之后。

sensitivity :控制比较敏感度。有下面这些值

'base':仅比较基础字符(忽略重音和大小写)。

'case':考虑大小写差异。

localeCompare的排序原理:

string.localeCompare(compareString, 'zh-CN')

在中文环境下会使用拼音(声母→韵母→声调)的字典顺序进行排序。

示例:'北方', 会排在 '北京' 的前面。

localeCompare实现排序

const arr = [
'南宁','阿坝州', '河池', '柳州',
'桂林','北安州', '贺州', '梧州','北院', '北京'
];
const newArr = arr.sort((a, b) => a.localeCompare(b, 'zh-Hans-CN'));
console.log(newArr, arr);

const nameArr = [
{"text": "北京", "value": "北京"},
{"text": "阿坝州", "value": "阿坝州"},
{"text": "桂林", "value": "桂林"},
{"text": "南宁", "value": "南宁"},
]; const newArr = nameArr.sort((a, b) => a.text.localeCompare(b.text, 'zh-Hans-CN'));
console.log(newArr, nameArr);

我们发现使用localeCompare确实可以按照拼音进行排序啦。

有机智的小伙伴会说:如果浏览器不支持呢?

我查询过资料,确实会有这样的情况、

如:localeCompare函数在X5内核(android版的微信浏览器)的浏览器不兼容该函数,请注意使用。

我们可以先去检查一下,是否支持排序,如果不支持就不进行排序。

因为:不排序总比报错要强上不少。

避免依赖localeCompare的返回值

ECMAScript 规范仅要求localeCompare返回正/负/零。

但是不同浏览器可能返回 -1、-2、1、2 等

检查浏览器是否支持localeCompare排序

在使用 localeCompare 方法之前,先检测浏览器是否支持 localeCompare 方法。

如果支持,则返回 true,否则返回 false。

function isPinYinSupported() {
try {
// 创建测试字符串
const testArr = ['北京', '上海','成都']
testArr.sort((a, b) => a.localeCompare(b, 'zh-Hans-CN'))
// 如果未抛出错误,表示支持排序
return true
} catch (e) {
// 如果抛出错误,表示不支持
return false
}
}

Intl.Collator 的介绍

Intl.Collator 用于根据语言环境对字符串进行比较和排序。

是国际化(i18n)API 的核心组件。

语法:new Intl.Collator(locales, options)

locales: 指定区域设置,如'zh-CN'表示简体中文

options是一个对象,有下面这些值

-caseFirst:控制大小写排序顺序,可选upper(大写优先), lower(小写优先)

-numeric:设为true时,按数字顺序比较字符串。如“苹果10”排在“苹果2”之后。

-ignorePunctuation:设为true时忽略标点符号,例 “你好,世界” 和 “你好世界” 会被视为相同

-sensitivity:控制比较的敏感度。

--它的值有:case(考虑大小写),base(仅比较基础字符,忽略重音和大小写)

排序时,忽略标点符号

// gnorePunctuation:设为true时忽略标点符号
const collatorIgnorePunct = new Intl.Collator('zh-CN', { ignorePunctuation: true });
console.log(collatorIgnorePunct.compare('你好,世界', '你好世界')); // 输出0,表示相等

排序时,照数字排序

// 按照数字排序
const arr = ['苹果10', '苹果14','苹果2']
// 缓存collator实例
const collator = new Intl.Collator('zh-CN', { numeric: true });
const sortedArr = arr.sort((a,b)=> collator.compare(a,b));
console.log(sortedArr); // ['苹果2', '苹果10', '苹果14']

Intl.Collator 的排序 a-z进行排序

const arr = [
'南宁','阿坝州', '河池', '柳州', '北方', '大连',
'桂林','北安州', '贺州', '梧州','北院', '北京'
];
// 缓存collator实例,使用Intl.Collator进行拼音排序,
const collator = new Intl.Collator('zh-CN');
const sortedArr = arr.sort((a,b)=> collator.compare(a,b));
console.log(sortedArr);

const arr = [
'南宁','阿坝州', '河池', '柳州', '北方', '大连',
'桂林','北安州', '贺州', '梧州','北院', '北京'
];
// 缓存collator实例,使用Intl.Collator进行拼音排序
const collator = new Intl.Collator('zh-CN');
const sortedArr = arr.sort(collator.compare);
console.log(sortedArr);

Intl.Collator 的排序 z-a进行排序

const arr = [
'南宁','阿坝州', '河池', '柳州', '北方', '大连',
'桂林','北安州', '贺州', '梧州','北院', '北京'
];
// 缓存collator实例
const collator = new Intl.Collator('zh-CN');
// 在compare的时候使用compare(b, a)就是z-a进行排序了
const sortedArr = arr.sort((a, b) => collator.compare(b, a));
console.log(sortedArr);

检查浏览器是否支持 Intl.Collator

function supportIntlCollator(){
// 基础兼容性检查
if (typeof Intl === 'undefined' || typeof Intl.Collator !== 'function') {
return false;
}
// 区域支持检测
try {
new Intl.Collator('zh-CN');
return true;
} catch (e) {
// 捕获两种错误类,说明不支持:
return false;
}
}
console.log(supportIntlCollator())

Intl.Collator 和 localeCompare 的区别

当需重复比较大量字符串(如万级数组排序)时,Intl.Collator 相比localeCompare更高效。

Intl.Collator适合多次重复比较,localeCompare 适合单次比较。

因为 Intl.Collator 预先缓存语言规则。

[重要]频繁排序时,建议缓存collator实例以提高性能

sort排序会改变原数组

const nameArr = [
{"text": "北京", "value": "北京"},
{"text": "阿坝州", "value": "阿坝州"},
{"text": "桂林", "value": "桂林"},
{"text": "南宁", "value": "南宁"},
]; const newArr = nameArr.sort((a, b) => a.text.localeCompare(b.text, 'zh-Hans-CN'));
console.log('新数组', newArr);
console.log('原数组', nameArr);

js实现根据汉字的拼音按照a-z的方式进行排序的更多相关文章

  1. js版本的汉字转拼音

    var PinYin = {"a":"\u554a\u963f\u9515","ai":"\u57c3\u6328\u54ce\u ...

  2. js 中实现 汉字按拼音排序

    let arr = ["贵州省", "江苏省", "江西省", "浙江省", "四川省", &quo ...

  3. JavaScript 汉字与拼音互转终极方案 附JS拼音输入法

    转:http://www.codeceo.com/article/javascript-pinyin.html 前言 网上关于JS实现汉字和拼音互转的文章很多,但是比较杂乱,都是互相抄来抄去,而且有的 ...

  4. 【干货】JS版汉字与拼音互转终极方案,附简单的JS拼音输入法

    前言 网上关于JS实现汉字和拼音互转的文章很多,但是比较杂乱,都是互相抄来抄去,而且有的不支持多音字,有的不支持声调,有的字典文件太大,还比如有时候我仅仅是需要获取汉字拼音首字母却要引入200kb的字 ...

  5. js中文汉字按拼音排序

    JavaScript 提供本地化文字排序,比如对中文按照拼音排序,不需要程序显示比较字符串拼音. String.prototype.localeCompare 在不考虑多音字的前提下,基本可以完美实现 ...

  6. 用JS实现汉字转拼音

    <!DOCTYPE HTML> <html> <head> <title>用JS实现汉字转拼音</title> <meta chars ...

  7. JS版汉字与拼音互转终极方案,附简单的JS拼音输入法

    原文:http://www.cnblogs.com/liuxianan/p/pinyinjs.html 前言 网上关于JS实现汉字和拼音互转的文章很多,但是比较杂乱,都是互相抄来抄去,而且有的不支持多 ...

  8. js汉字转拼音首字母

    js汉字转拼音首字母 2018-04-09 阅读 1018 收藏 1 原链:segmentfault.com 分享到:   前端必备图书<JavaScript设计模式与开发实践> > ...

  9. JS版汉字与拼音互转终极方案,附简单的JS拼音

    前言 网上关于JS实现汉字和拼音互转的文章很多,但是比较杂乱,都是互相抄来抄去,而且有的不支持多音字,有的不支持声调,有的字典文件太大,还比如有时候我仅仅是需要获取汉字拼音首字母却要引入200kb的字 ...

  10. JS实现获取汉字首字母拼音、全拼音及混拼音的方法

    本文实例讲述了JS实现获取汉字首字母拼音.全拼音及混拼音的方法.分享给大家供大家参考,具体如下: 这里需要用到一个js获取汉字拼音的插件,可点击此处本站下载. 运行效果如下: 完整示例代码: ? 1 ...

随机推荐

  1. 红杉AI闭门会:AI 不再卖工具,而是卖收益

    AI创业失败,经验教训分享可私聊... 近来,AI圈最值得关注的应该是在旧金山召开的红杉资本AI峰会. 敏感的同学会清楚,钱在哪里,哪里就有发展,如果能迎合资本市场,那就有可能活得很好,所以我们今天就 ...

  2. pta求符合给定条件的整数集 C语言

    题目如下 给定不超过6的正整数A,考虑从A开始的连续4个数字.请输出所有由它们组成的无重复数字的3位数. 输入格式: 输入在一行中给出A. 输出格式: 输出满足条件的的3位数,要求从小到大,每行6个整 ...

  3. Win32汇编学习笔记01.环境配置

    Win32汇编学习笔记01.环境配置-C/C++基础-断点社区-专业的老牌游戏安全技术交流社区 - BpSend.net 环境配置 masm32下载 官网:http://www.masm32.com/ ...

  4. Linux grep 匹配多个关键字

      Linux grep 命令非常常用,经常用于匹配文本字符.基本语法如下: grep 'keyword'fileName.txt   如上所示,Linux grep 命令用于查找文件里符合指定条件的 ...

  5. HashMap之装载因子

          装载因子:load fator,散列表中关键字个数和散列表长度之比.她用于度量所有关键字填充哈希表后饱和的程度.       重哈希:rehash,亦或再散列,当装载因子达到指定阈值时,散 ...

  6. NOIp2020复赛游记

    NOIp2020复赛游记 T1 他们用的都是拓扑排序,但是我用的是\(bfs\)+\(online\)标记\(\dots\dots\)样例当然能过,但是会被卡成暴力. 不过,他们有人用拓扑时,要么把入 ...

  7. CC爬虫攻击测试与防护

    CC爬虫攻击测试与防护 本文章旨在对最基本的CC攻击进行测试与防护,本次测试的所有站点均为本人自建,没有也不会去攻击其他站点.希望各位读者能够遵循当地法律法规,不要做危害他人计算机的行为 测试流程 裸 ...

  8. js判断一个变量是否存在值得简单方法

    在编码过程中,有时候我们需要对一个变量判断其是否有值,这里有一种比较不错的方法判断: !!variable //返回True为存在值,返回False为不存在值 注意是双感叹号"!!" ...

  9. 现在的AI还能写出短剧剧本了?

    本文由 ChatMoney团队出品 现在大家打开抖音.小红书,琳琅满目,目光所能及的都是各种吸精剧情的小短剧,虽然这些短剧的制作成本低,但是作为编剧的要写脚本,可不认为这么容易啊......... 接 ...

  10. Java并发利器:CountDownLatch深度解析与实战应用

    Java并发利器:CountDownLatch深度解析与实战应用 多线程编程中,让主线程等待所有子任务完成是个常见需求.CountDownLatch就像一个倒计时器,当所有任务完成后,主线程才继续执行 ...