解决 JavaScript 中文排序的痛点
在 JavaScript 中,对中文内容进行排序一直以来都是个棘手的问题。如果直接调用 sort
方法,结果可能并不符合我们的预期。
一、问题分析
以下是一个需要排序的中文数组:
js
const names = ["张三", "李四", "王五", "赵六", "孙七"];
直接调用 names.sort(),得到的结果如下:
js
['孙七', '张三', '李四', '王五', '赵六']
显然,这不是我们期望的排序顺序。原因是sort
方法默认按字符串的 Unicode 编码进行排序。我们来看一下这些字的 Unicode 值:
js
"张".charCodeAt(0); // 24352
"李".charCodeAt(0); // 26446
"王".charCodeAt(0); // 29579
"赵".charCodeAt(0); // 36213
"孙".charCodeAt(0); // 23385
可以看到,"孙" 的 Unicode 编码小于 "张",因此在排序结果中排在前面。
二、目的
为了实现符合中文拼音规则的排序,我们需要一种更合理的排序方法。
三、使用 localeCompare
方法
localeCompare
是 JavaScript 中一个内置的字符串比较方法,允许指定语言环境来进行排序。在中文环境下,可以通过以下方式实现正确的中文排序:
1. 示例代码
js
const names = ["张三", "李四", "王五", "赵六", "孙七"];
names.sort((a, b) => a.localeCompare(b, 'zh-CN'));
console.log(names);
// ['李四', '孙七', '王五', '张三', '赵六']
优点:
- 简洁、无需额外依赖。
- 能处理大多数中文排序需求。
注意事项:
localeCompare
是基于浏览器的语言设置和实现,某些情况下可能对多音字处理不够准确。例如,"重" 可以发音为 chóng 或 zhòng,导致排序结果可能不符合预期。
2. Local列表
Locale | 语言/区域 | 说明 |
---|---|---|
zh-CN | 中文(简体,中国) | 默认用于简体中文排序 |
zh-TW | 中文(繁体,台湾) | 繁体中文排序 |
zh-HK | 中文(繁体,香港) | 香港繁体中文排序 |
en-US | 英语(美国) | 美国英语 |
en-GB | 英语(英国) | 英国英语 |
fr-FR | 法语(法国) | 法国法语 |
fr-CA | 法语(加拿大) | 加拿大法语 |
de-DE | 德语(德国) | 德国语言环境 |
es-ES | 西班牙语(西班牙) | 西班牙西班牙语 |
es-MX | 西班牙语(墨西哥) | 墨西哥西班牙语 |
ja-JP | 日语(日本) | 日本日语环境 |
ko-KR | 韩语(韩国) | 韩国韩语 |
ru-RU | 俄语(俄罗斯) | 俄罗斯俄语 |
ar-SA | 阿拉伯语(沙特阿拉伯) | 沙特阿拉伯阿拉伯语 |
pt-PT | 葡萄牙语(葡萄牙) | 葡萄牙葡萄牙语 |
pt-BR | 葡萄牙语(巴西) | 巴西葡萄牙语 |
it-IT | 意大利语(意大利) | 意大利语言环境 |
hi-IN | 印地语(印度) | 印度印地语 |
th-TH | 泰语(泰国) | 泰国语言环境 |
vi-VN | 越南语(越南) | 越南语环境 |
使用示例:
js
const names = ["张三", "李四", "王五", "赵六", "孙七"];
// 简体中文排序
names.sort((a, b) => a.localeCompare(b, 'zh-CN'));
console.log(names);
// 繁体中文排序(香港)
names.sort((a, b) => a.localeCompare(b, 'zh-HK'));
console.log(names);
// 英语(美国)排序
const englishNames = ["apple", "Banana", "cherry"];
englishNames.sort((a, b) => a.localeCompare(b, 'en-US'));
console.log(englishNames);
注意事项:
- 默认情况下,如果不指定 locale,
localeCompare
会使用运行环境的默认语言环境。 - 某些语言环境可能存在微小的排序差异,例如简体中文和繁体中文。
- 浏览器或 JavaScript 引擎需要支持指定的语言环境,部分较旧环境可能不支持所有 locale 标识符。
四、使用拼音库处理多音字
对于多音字排序的场景,推荐使用开源拼音库(如 pinyin 或 pinyin-pro),它们可以准确地将中文转换为拼音并排序。
1. 示例代码(基于pinyin-pro)
- 安装
pinyin-pro
库
bash
npm install pinyin-pro
- 使用拼音库进行排序:
js
import { pinyin } from 'pinyin-pro';
const names = ["张三", "李四", "王五", "赵六", "孙七", "重阳"];
names.sort((a, b) => pinyin(a, { toneType: 'none' }).localeCompare(pinyin(b, { toneType: 'none' })));
console.log(names);
// ['李四', '孙七', '王五', '张三', '重阳', '赵六']
优点:
- 准确处理多音字。
- 提供灵活的配置(如带声调、不带声调等)。
缺点:
- 增加了项目体积。
五、总结
- 对于一般中文排序需求,可以直接使用
localeCompare
:
js
names.sort((a, b) => a.localeCompare(b, 'zh-CN'));
- 如果需要更精确的排序(包括多音字),可以使用拼音库:
js
import { pinyin } from 'pinyin-pro';
names.sort((a, b) => pinyin(a).localeCompare(pinyin(b)));
根据实际需求选择合适的方法,既能保持代码的简洁性,又能满足用户的体验需求。