【问题标题】:Sorting cyrillic words with accents对带有重音符号的西里尔字母进行排序
【发布时间】:2018-04-27 10:20:15
【问题描述】:

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

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>");
    });
}

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

【问题讨论】:

  • 您能否提供一个包含要排序的字符串的独立示例?您还检查过Intl.Collator.supportedLocalesOf('ru') 返回的内容吗?您使用的是什么浏览器(和版本)?
  • 排序后的值也可以分享一下吗?
  • 我添加了一个很好地说明问题的单词列表。似乎问题只涉及以变音字符开头的单词。 Intl.Collator.supportedLocalesOf('ru') 返回 ["ru"]。我正在使用 Chrome 62。
  • @gurvinder372 这是排序后的单词列表。

标签: javascript arrays sorting dictionary diacritics


【解决方案1】:

您尚未在options 中提供sensitivity。可能默认值为 'variant'(我在 Chrome 的控制台中尝试过),而您需要 'base'

【讨论】:

  • 但这是错误的顺序 :) á-words 不应该在最后。
  • 实际上,它不适用于带有西里尔符号的较大字符串集。在这种情况下,应该像.sort((x,y) =&gt; x.localeCompare(y, 'ru')) 这样添加第二个参数 - 以指定我们要使用的字母表。它的工作原理与 Intl.Collat​​or 对象相同。
  • 我在丹麦语中为 Chromium 找到了类似的错误 reported
  • Chromium 指的是ICU project,即指的是CLDR,所以很难找出谁是错误报告的接收者:)
  • 我不认为变音符号与任何字母都绑定在一起。它们都与Unicode中的separated section相关(除了包含在字母表中的Й和Ё)
【解决方案2】:

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

由于带有重音的字符通常被组合并保留为单个字符,因此带有重音的西里尔字母“a”和拉丁文“a”成为同一个字符。它使标准排序失败。

作为一种解决方法,我建议

  1. .toLowerCase()规范化大小写
  2. 使用.normalize('NFD')将单个字符扩展为'基本字符+重音字符'系列
  3. 使用.replace() 删除任何变音字符
  4. 使用标准.sort()

我相信它应该有效。

【讨论】:

    猜你喜欢
    • 2014-09-11
    • 1970-01-01
    • 2021-03-31
    • 2022-06-27
    • 1970-01-01
    • 1970-01-01
    • 2011-11-19
    • 1970-01-01
    相关资源
    最近更新 更多