Сортировка русского / английского списка

У меня есть следующий массив, в котором есть английские и русские слова:

[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

Проблема в том, что он сортирует список, но сортирует их отдельно, мне нужно, чтобы русская буква «А» была рядом с английской буквой «А», если это имеет смысл. Как я могу этого достичь?

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 будучи последним на английском языке, так что лучше не делать этого с точки зрения UX.

1

Другие решения

Вы можете использовать расширение 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);
});

Я добавил исходные строки к окончательному сравнению, чтобы дифференцировать случаи, когда транслитерация русской и латинской строк производит одинаковую транслитерацию.

1