使用 localeCompare 对数组排序时顺序错乱
问题描述:
使用 localeCompare 对一个字符串数组按名称排序
const arr = ['我', 'B', 'c', 'C', 'b', '干活', '233', '1024', '211', '吃饭'];
arr.sort((a, b) => a.localeCompare(b));
// ["1024", "211", "233", "吃饭", "干活", "我", "b", "B", "c", "C"]
但在 Mac 和 Windows 上对大小写字母的排序规则不一致
而且在中文环境下,默认的排序顺序是:数字 > 中文 > 字母,产品需要改为:数字 > 字母 > 中文
分析原因:
localeCompare 可以传入第二个参数 locales 和第三个参数 options 来控制排序规则
// 这两个参数的详细配置查看这里: Intl.Collator() constructor
如果没有传入这两个参数,localeCompare 就会读取当前系统配置的语言环境,最终的结果就会有差异
解决方案:
一般情况下,传入 locales 就可以了
数字 > 中文 > 小写字母 > 大写字母
arr.sort((a, b) => a.localeCompare(b, 'zh-CN-u-kf-lower'));
// ["1024","211","233","吃饭","干活","我","b","B","c","C"]
数字 > 中文 > 大写字母 > 小写字母
arr.sort((a, b) => a.localeCompare(b, 'zh-CN-u-kf-upper'));
// ["1024","211","233","吃饭","干活","我","B","b","C","c"]
数字 >小写字母 > 大写字母 > 中文
arr.sort((a, b) => a.localeCompare(b, 'en-US-u-kf-lower'));
// ["1024","211","233","b","B","c","C","吃饭","干活","我"]
数字 > 大写字母 > 小写字母 > 中文
arr.sort((a, b) => a.localeCompare(b, 'en-US-u-kf-upper'));
// ["1024","211","233","B","b","C","c","吃饭","干活","我"]