用重音排序西里尔文字

Sorting cyrillic words with accents

我在对用西里尔字母(带重音符号)编写的字符串数组进行排序时遇到了问题。以下解决方案将字符串开头带和不带变音符的字符串分开排序。

function sorting(){
    let words = document.querySelectorAll(".dictionary");   
    let unsorted = [];
    let collator = new Intl.Collator('ru', {sensitivity: 'base'});
    words.forEach(s => {
        unsorted.push(s.textContent);
    });
    unsorted.sort(collator.compare);
    unsorted.forEach(s => {
        document.write("<p>" + s + "</p>");
    });
}

编辑
这是排序前的数组:
[..., 'áвтор', ..., 'авиабилéт', ..., 'янтáрный', ..., 'Áвстрия', 'áвтор', 'автостóп'];
这是排序后的结果:
["авиабилéт", "автостóп", ..., "янтáрный", ..., "Áвстрия", "áвтор"]
这就是我想要的
['авиабилéт', 'Áвстрия', 'áвтор', 'автостóп', ..., 'янтáрный', ...];

您没有在 options 中提供 sensitivity。可能默认值是 'variant'(我在 Chrome 的控制台中试过)而你需要 'base'

经过一些调查,我认为这是 ICU 项目或 CLDR 库范围内的错误。

由于带重音的字符通常组合在一起并保持为单个字符,因此带重音的西里尔文 'a' 和拉丁文 'a' 成为相同的字符。它使标准排序失败。

作为解决方法,我建议

  1. 使用 .toLowerCase()
  2. 规范化大小写
  3. 使用 .normalize('NFD') 将单个字符扩展为 'base character + accent character'
  4. 系列
  5. 删除任何带有 .replace()
  6. 的变音字符
  7. 使用标准 .sort()

我相信它应该有效。