У меня есть следующий массив, в котором есть английские и русские слова:
[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
Проблема в том, что он сортирует список, но сортирует их отдельно, мне нужно, чтобы русская буква «А» была рядом с английской буквой «А», если это имеет смысл. Как я могу этого достичь?
Вы можете попробовать создать агрегированный массив символов, таких как:
$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.
Вы можете использовать расширение 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);
});
Я добавил исходные строки к окончательному сравнению, чтобы дифференцировать случаи, когда транслитерация русской и латинской строк производит одинаковую транслитерацию.