排序:为什么 arr.sort() 把 Z 排在 a 前面
["Z","a"].sort() 得到 ["Z","a"] —— 默认的 sort() 按 UTF-16 码元值逐个比较,而大写字母的码点全在小写之前,带音标的字母又全被甩到 ASCII 之后,"file10" 还会排在 "file9" 前。真正「按某种语言的字典序」排序,由 Unicode Collation Algorithm(UCA)定义,JS 里走 Intl.Collator。和
拼音那页同理:排序规则不写在码点里,是另一份按 locale 调的权重表。
默认 sort() 是码元序,不是字母序
左边是 arr.sort()(按 UTF-16 码元),右边是 arr.sort(new Intl.Collator(locale).compare)。位置不同的行会高亮 —— 码元序里大写聚一堆、小写聚一堆、带音标的垫底,根本不是人读的顺序:
arr.sort()按 UTF-16 码元值
Intl.Collator按语言的字典序
三层权重:sensitivity 决定「忽略到哪一层」
UCA 给每个字符算多级权重:primary(基字母,a vs b)、secondary(变音,a vs á)、tertiary(大小写,a vs A)。Intl.Collator 的 sensitivity 选项就是「比到第几层」 —— 比得越浅,越多字符被当成相等:
每格:collator.compare(左, 右) → < / = / >(= 高亮表示这一层把它们看成相等)
sensitivity:'base';区分音标但不分大小写用 'accent';完整排序(默认)用 'variant'。注意 compare(a,b)===0 表示「排序意义上相等」,不等于 === —— 比较前若还担心同字多形,先
normalize。
locale 不同,顺序就不同
同一组字母,不同语言排出的顺序不一样。瑞典语把 å ä ö 放到 z 之后(字母表末尾),德语把 ä 当 a 的变体排在一起,英语则把所有音标都当次级差异:
把 a z ä ö å 用各 locale 排序
numeric:让 file10 排在 file9 之后
字符串里的数字,默认按字符比('1' < '9',所以 "file10" 排在 "file9" 前)。Intl.Collator 开 numeric:true 会把连续数字当数值比 —— 这正是文件管理器里「自然排序」的做法:
默认数字逐字符比
numeric: true连续数字当数值比
sort() 或 < —— 那是码元序。用 Intl.Collator(locale, { sensitivity, numeric }),把「按哪种语言、忽略到哪层、数字怎么比」交给标准。中文排序传 'zh' 即按拼音,和
拼音那页是一回事。