必须显式配置 Intl.Collator 的 collation: 'pinyin'、sensitivity: 'base' 和 numeric: true,并复用实例、预处理多音字、统一字符集,才能实现正确高效的中文多维数组排序。
直接用 Intl.Collator 对多维数组排序,不能只传个 locale 就完事。关键在三点:明确启用拼音规则、正确处理嵌套字段、避免重复创建 collator 实例。否则排序结果错乱,性能还可能因反复初始化拖慢。
仅写 new Intl.Collator('zh-CN') 会退化为 Unicode 码点排序,「张」可能排在「李」前面——这不是 bug,是默认行为。真正按拼音(如 li、wang、zhang)排序,需强制指定:
错误示例:new Intl.Collator('zh-CN') 或 new Intl.Collator('zh-CN', { usage: 'search' }) —— 后者会弱化排序精度,不适用于列表展示。
假设你有如下用户数组,需按 name 拼音升序,同名时按 age 数值降序:
正确做法是复用一个 collator 实例,并在 compare 函数中分层判断:
collator.compare(a.name, b.name) 比姓名拼音b.age - a.age 实现 age 降序toString() 或正则提取避免写成:arr.sort((a, b) => new Intl.Collator('zh', { collation: 'pinyin' }).compare(a.name, b.name))——每次比较都新建对象,性能损耗明显。
Intl.Collator 对「重庆」「行长」「重叠」等多音字采用固定读音(如统一按 chóng qìng),无法上下文感知。若业务要求「重庆」按 zhòng qìng 排序(如地名专题页),就得前置处理:
pinyin-pro)对目标字段预标注,生成带确定读音的临时键,例如 { name: '重庆', pinyinKey: 'zhongqing' }
Intl.Collator('zh', { sensitivity: 'base' }) 对 pinyinKey 排序——此时已无多音干扰zh-convert),再走拼音排序;或按场景切 locale,如台企数据用 'zh-Hant-TW'
高频重排(如搜索过滤、实时筛选)下,反复调用 Array.prototype.sort() 是瓶颈。建议:
stableSort 或虚拟滚动跳过全量重排(a, b) => -collator.compare(a.name, b.name),别重建实例不复杂但容易忽略:多维排序不是功能堆砌,而是规则分层 + 实例复用 + 数据预处理的组合拳。