功能说明
naturalSort 按人类阅读习惯排序文件名、版本标签、表格列名等文本,使 item2 排在 item10 之前,而不是按字符编码得到 item10 在前的顺序。createNaturalComparator 允许指定语言与 Intl.Collator 选项,默认忽略大小写和重音差异。naturalSort 返回新数组,不修改调用方数据,适合表格排序、文件列表和目录树展示。
关键代码
比较器由 Intl.Collator 驱动,开启 numeric 后连续数字会按数值比较,sensitivity 设为 base 让大小写与重音不参与主排序。collator.compare 返回零时,代码再用字符串的小于比较做平局判定,确保不同运行时对等价字符串仍给出稳定顺序,避免排序结果抖动。工厂函数把 collator 提升到闭包外,批量排序时无需反复创建。
使用注意
numeric 只识别连续数字,小数点和负号仍按普通字符处理,若要排序带符号小数应先解析成数值。不同 locale 的排序习惯不同,面向国际用户时应传入明确语言而不是依赖运行环境默认值。忽略大小写意味着 A 与 a 的比较结果为零,若业务要求大写优先需额外传入 caseFirst 选项。排序稳定性还依赖底层 sort,现代引擎已保证稳定。
验证方式
用包含 item1、item2、item10 的数组断言自然顺序,并测试纯数字字符串、带前导零的编号与混合中英文标签。构造大小写不同但 collator 判定相等的值,确认平局规则给出确定顺序。再测试空数组、单元素、非数组输入,以及传入自定义 locale 和 caseFirst 选项时的结果差异。
代码示例
export function createNaturalComparator(locale = "en", options = {}) {
const collator = new Intl.Collator(locale, {
numeric: true,
sensitivity: "base",
...options,
});
return (left, right) => {
const a = String(left);
const b = String(right);
return collator.compare(a, b) || (a < b ? -1 : a > b ? 1 : 0);
};
}
export const naturalCompare = createNaturalComparator();
export function naturalSort(values, compare = naturalCompare) {
if (!Array.isArray(values)) throw new TypeError("values must be an array");
return [...values].sort(compare);
}