【问题标题】:Sorting Russian/English list排序俄语/英语列表
【发布时间】:2014-11-28 11:02:44
【问题描述】:

我有以下数组,其中包含英语和俄语单词:

[0]  => Airline_1
[1]  => Second Air
[2]  => Авиатор
[3]  => Аврора

我正在使用以下函数对其进行排序:

    uasort($newCompanyList, function ($a, $b) {
        $at = iconv('UTF-8', 'ASCII//TRANSLIT', $a);
        $bt = iconv('UTF-8', 'ASCII//TRANSLIT', $b);
        return strcmp($at, $bt);
    });

预期的结果是这样的:

[0]  => Airline_1
[2]  => Авиатор
[3]  => Аврора
[1]  => Second Air

问题是它确实对列表进行了排序,但它对它们进行了单独排序,如果有意义的话,我需要将俄语“A”放在英语“A”旁边。我怎样才能做到这一点?

【问题讨论】:

  • 我猜这是不可能的
  • 您无法将西里尔字母与希腊字母进行排序,因为它们彼此不匹配。顺序不同,有字母反之不知道。
  • iconv('UTF-8', 'ASCII//TRANSLIT', --); 不支持西里尔字母。要音译西里尔字母,您需要构建一个自定义函数following these rules:
  • 创建一个多维数组,其中第二个值是带有拉丁字符的西里尔单词的含义,并按此排序。

标签: php sorting cyrillic


【解决方案1】:

您可以尝试制作一个聚合的字符数组,例如:

$customAlfabet = array(
    'A', // EN
    'А', // RU
    'B', // EN
    'Б', // RU
    ...
);

然后根据数组的数字键应用排序。

uasort($newCompanyList, function ($a, $b) {
    if ($a[0] > $b[0]) {
        return 1;
    } elseif ($a[0] < $b[0]) {
        return -1;
    }
    return 0;
});

最好在这里应用递归,如果第一个字符相同 - 检查第二个字符,第三个等。

注意,例如字符З,其发音与Z相当,在俄语字母中被定位为第9个字符,而Z是英语中的最后一个,所以从用户体验的角度来看,最好不要这样做。

【讨论】:

    【解决方案2】:

    您可以使用 Intl 扩展和 Transliterator 对象,如下所示:

    $transliterator = Transliterator::create('Any-Latin; Latin-ASCII;');
    uasort($newCompanyList, function ($a, $b) use ($transliterator) {
        $at = $transliterator->transliterate($a);
        $bt = $transliterator->transliterate($b);
        return strcmp($at.$a, $bt.$b);
    });
    

    我已将原始字符串附加到最终比较中,以区分俄语字符串的音译和拉丁语字符串的音译产生相同音译的情况。

    【讨论】:

    • 考虑到Transliterator 在处理俄语单词时很糟糕,这不是最好的方法。 АЯ 是俄语 alfabet 的第一个和最后一个字母,都被音译为英语的“a”,而“Я”的真正发音有点像“ya”。
    • 嗯,你是对的。刚刚测试了“Ямал”,它产生了“amalt”。令人失望。因此,在这种情况和类似情况下,手动音译似乎是更好的方法。对于更一般的用途,我还没有发现任何其他工具可以更好地音译。我的意思是当一个人不仅需要支持英语/俄语,还需要支持其他语言时,编写手动音译表很麻烦。
    • 是的,它只是音译最适合阅读未知字符。它有它的用例,这只是一个例外。虽然,有更好的俄语音译库,如果您可能需要它们,here is 一个不错的(俄语文章,但代码不是:))
    猜你喜欢
    • 2015-09-06
    • 1970-01-01
    • 2011-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多