Сортировка китайских имен в PHP

У меня есть массив, каждый элемент содержит имя и фамилию:

$input = [
  [
    'firstName' => 'foo',
    'lastName' => 'bar',
  ]
];

Для большинства пользователей они в основном написаны латинским алфавитом, но некоторые написаны на китайском языке.

Как бы я отсортировал этот список имен с помощью PHP?

Меня также интересует конвенция. Я знаю, что в языках, использующих латиницу-1, иногда имя идет первым, а иногда последним. Мне любопытно, аналогична ли эта ситуация в мандаринском диалекте, или один из них обычно предпочтительнее другого.

И, наконец, мне интересно, есть ли разница между сортировкой имен и сортировкой слов, как в словаре.


person Evert    schedule 30.04.2015    source источник
comment
Основная идея любой сортировки заключается в том, что у вас должны быть элементы, которые можно сравнивать. Я не вижу этого, если данные содержат латинские символы и китайские символы.   -  person BigScar    schedule 30.04.2015
comment
Кажется, что в китайском нет даже жесткого набора правил порядка символов: cantonese.sheik.co.uk/phorum/read.php?1,122672,122681   -  person Jeremy Harris    schedule 30.04.2015
comment
Один из вариантов @BigScar заключается в том, что если список имен содержит смешанные латинские и китайские имена, мы просто выбираем одно из этих двух и отображаем его первым. Меня больше беспокоит правильная сортировка китайских имен между собой. Любопытно, есть ли какие-то лучшие практики.   -  person Evert    schedule 30.04.2015
comment
Для китайского/корейского/японского языка вы всегда указываете сначала фамилию. В примере с Ким Чен Иром Ким — это фамилия, а Чен Ир — имя. Мы сталкиваемся с проблемой японского и китайского языков, использующих ханзи/кандзи для имен, и я считаю, что оба языка сортируют имена по-разному.   -  person Muhammad Abdul-Rahim    schedule 30.04.2015
comment
Я провел некоторое исследование японской сортировки, @Evert, и это очень нетривиально, потому что иероглифы могут произноситься по-разному в зависимости от контекста. Многие сайты в Японии, такие как Amazon, просят пользователя вводить свое имя не только кандзи, но и кана. Кану можно легко отсортировать, так как это произношение 1-к-1. Кандзи не может. 淳子 может быть Дзюнко, Ацуко, Киёко, Акико... Как выглядит китайская амазонка? У них есть китайский амазон?   -  person Muhammad Abdul-Rahim    schedule 06.05.2015


Ответы (1)


Действительно интересный вопрос! Каждый символ имеет значение Unicode. Большая часть сортировки выполняется через это. Поскольку латинские буквы находятся в диапазоне ASCII, эти имена всегда появляются первыми. Функция PHP asort будет учитывать Unicode. Вот ввод для рассмотрения:

$input = [
    [
        "firstName" => "一",
        "lastName"  => "風"
    ],
    [
        "firstName" => "이",
        "lastName"  => "정윤"
    ],
    [
        "firstName" => "Mari",
        "lastName"  => "M"
    ],
    [
        "firstName" => "三",
        "lastName"  => "火"
    ],
];

Давайте резюмируем то, что я ожидаю увидеть, предполагая, что мы сортируем по имени:

  • Первое латинское имя (Mari M)
  • Далее идут имена ханзи/кандзи/хангыль. Я не знаю, каковы значения этих имен, так что мы должны это выяснить.

Давайте преобразуем первый символ имен во что-то числовое. Опять же, мы используем Unicode для этого преобразования:

  • 一 is 0x4E00
  • 이 is 0xC774
  • M is 0x004D
  • 三 is 0x4E09

Таким образом, я ожидаю увидеть по порядку:

  • M

Вот мой код с использованием asort:

$nameByFirst = [];
foreach( $input as $i )
{
    $nameByFirst[] = $i["firstName"]." ".$i["lastName"];
}
asort($nameByFirst);

И мой метод печати:

$i = 1;
foreach( $nameByFirst as $name )
{
    echo $i.'.  '.$name."<br>";
    $i++;
}

И мой вывод:

  1. Мари М
  2. 一 風
  3. 三 火
  4. 이 정윤

Мои результаты, как вы можете видеть выше, в порядке. Сначала латынь, затем ханзи/кандзи, потом хангыль. Я считаю, что Unicode ближе всего к простой сортировке, поэтому я предпочитаю использовать его. Я не уверен на 100% в том, как Unicode присвоил значения ханзи/кандзи/хангылю, но я готов доверять предоставленному ими порядку, особенно из-за его простоты.

person Muhammad Abdul-Rahim    schedule 30.04.2015
comment
asort обычно сортирует на основе значений байтов, а не кодовых точек Unicode, поэтому я знаю, что это решение не может быть полным. Многие языки имеют модификаторы в различных формах нормализации юникода, что нарушает порядок. Даже для latin1 вы могли бы считать неправильным, если фамилия или имя были написаны без заглавной буквы. - person Evert; 30.04.2015
comment
Честная оценка. Для латиницы существует понятие заглавных букв, но не так много для других языков. Однако я вижу в этом смысл, поскольку каждый язык имеет свои собственные способы упорядочения по алфавиту. Я подумаю об этом еще. Вот связанное чтение: stackoverflow.com/questions/5698226/sort-for-japanese - person Muhammad Abdul-Rahim; 30.04.2015
comment
Это существует: php.net/manual/en/collator.construct.php Но недостаток в том, что мне нужно скормить ему язык для сортировки. Это сложно, потому что мой вариант использования — это, по сути, огромная адресная книга, из которой я заранее не знаю локали =) - person Evert; 30.04.2015