PHP数组排序和与波斯语字母表的兼容性

Far*_* Rn 10 php arrays sorting

我试图先按照它的值对数组进行排序,然后按它的键进行排序,但是对于波斯语字符,php并不是很好.
波斯语字母表类似于阿拉伯字母,除了一些额外的字符,如'گچپژک'和PHP在波斯语字母表中排序阿拉伯字母方面做得很好,但其余的不在他们的顺序中.

例如

$str = '? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?';
$arr = explode(' ', $str);
Run Code Online (Sandbox Code Playgroud)

将按$arr正确的字母顺序创建一个包含所有波斯语字母的数组().如果我将它洗牌并使用asort如下功能:

shuffle($arr);
asort($arr);
var_dump($arr);
Run Code Online (Sandbox Code Playgroud)

它会像这样结束:

    array
        2 => string '?'
        1 => string '?'
        22 => string '?'
        29 => string '?'
        20 => string '?'
        12 => string '?'
        21 => string '?'
        18 => string '?'
        6 => string '?'
        3 => string '?'
        27 => string '?'
        17 => string '?'
        11 => string '?'
        25 => string '?'
        5 => string '?'
        16 => string '?'
        8 => string '?'
        26 => string '?'
        14 => string '?'
        9 => string '?'
        0 => string '?'
        7 => string '?'
        10 => string '?'
        28 => string '?'
        24 => string '?'
        23 => string '?'
        13 => string '?'
        19 => string '?'
        4 => string '?'
        15 => string '?'
Run Code Online (Sandbox Code Playgroud)

这是错的!

第24项应在第1项之后,第23项应在20之后,依此类推.

如何编写一个与PHP自己的排序函数类似的函数?或许有一种方法可以让PHP函数适用于波斯语字符?

Sha*_*tta 5

我编写了以下函数来为任何给定字符返回UTF-8代码点:

function utf8_ord($str) {
    $str = (string) $str;
    $ord = ord($str);
    $ord_b = decbin($ord);

    if (strlen($ord_b) <= 7) 
      return $ord;
    $len = strlen(strstr($ord_b, "0", true));

    if ($len < 2 || $len > 4 || strlen($str) < $len) 
      return false;
    $val = substr($ord_b, $len + 1);

    for ($i = 1; $i < $len; $i++) {
        $ord_b = decbin(ord($str[$i]));
        if ($ord_b[0].$ord_b[1] != "10") 
          return false;
        $val. = substr($ord_b, 2);
    }
    $val = bindec($val);
    return (($val > 0x10FFFF) ? null : $val);
}
Run Code Online (Sandbox Code Playgroud)

现在,让我们找出数组中字符的UTF-8代码点:

$str = '? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?';
$arr = explode(' ', $str);
print_r(array_map("utf8_ord", $arr));
Run Code Online (Sandbox Code Playgroud)

输出将是:

Array
(
    [0] => 1575
    [1] => 1576
    [2] => 1662
    [3] => 1578
    [4] => 1579
    [5] => 1580
    [6] => 1670
    [7] => 1581
    [8] => 1582
    [9] => 1583
    [10] => 1584
    [11] => 1585
    [12] => 1586
    [13] => 1688
    [14] => 1589
    [15] => 1590
    [16] => 1591
    [17] => 1592
    [18] => 1593
    [19] => 1594
    [20] => 1601
    [21] => 1602
    [22] => 1705
    [23] => 1711
    [24] => 1604
    [25] => 1605
    [26] => 1606
    [27] => 1608
    [28] => 1607
    [29] => 1740
)
Run Code Online (Sandbox Code Playgroud)

它清楚地表明字符顺序不正确,需要进行排序。我不懂波斯语,所以我无法确定UTF-8波斯语字母是否存在错误。但是我只能说PHP可以正常工作。


Sae*_*eed 5

以及获取您可以使用的可用区域设置

print_r(ResourceBundle::getLocales(''));
Run Code Online (Sandbox Code Playgroud)

我两者'fa''fa_IR'可用,但'fa_IR'仍然返回 false,所以我用来'fa'测试它:

setlocale(LC_ALL, 'fa');
asort($arr, SORT_LOCALE_STRING);
var_dump($arr);
Run Code Online (Sandbox Code Playgroud)

但这对我来说仍然没有按正确的顺序排序......

因此,经过更多的谷歌搜索后,最终对我来说对 Unicode 波斯字母进行排序的解决方案是使用Collat ​​or 类:

$col = new \Collator('fa_IR');
$col->asort($arr);
var_dump($arr);
Run Code Online (Sandbox Code Playgroud)

我知道这个问题已经很老了,但这可能仍然可以帮助新来的人寻找这个问题的答案。


Yus*_*iri 5

要按波斯语字符对数组进行排序,首先请注意 Unicode 标准中的某些字符未正确对齐。\n在这种情况下,我的建议是创建一个常规的波斯语字符数组,并根据该数组排列主题数组。\nfor例子:

\n\n
function persianSort($item1, $item2){\n    $persian_characters = [\n        1 =>  \'\xd8\xa7\',\n        2 =>  \'\xd8\xa8\',\n        3 =>  \'\xd9\xbe\',\n        4 =>  \'\xd8\xaa\',\n        5 =>  \'\xd8\xab\',\n        6 =>  \'\xd8\xac\',\n        7 =>  \'\xda\x86\',\n        8 =>  \'\xd8\xad\',\n        9 =>  \'\xd8\xae\',\n        10 =>  \'\xd8\xaf\',\n        11 =>  \'\xd8\xb0\',\n        12 =>  \'\xd8\xb1\',\n        13 =>  \'\xd8\xb2\',\n        14 =>  \'\xda\x98\',\n        15 => \'\xd8\xb3\',\n        16 => \'\xd8\xb4\',\n        17 =>  \'\xd8\xb5\',\n        18 =>  \'\xd8\xb6\',\n        19 =>  \'\xd8\xb7\',\n        20 =>  \'\xd8\xb8\',\n        21 =>  \'\xd8\xb9\',\n        22 =>  \'\xd8\xba\',\n        23 =>  \'\xd9\x81\',\n        24 =>  \'\xd9\x82\',\n        25 =>  \'\xda\xa9\',\n        26 =>  \'\xda\xaf\',\n        27 =>  \'\xd9\x84\',\n        28 =>  \'\xd9\x85\',\n        29 =>  \'\xd9\x86\',\n        30 =>  \'\xd9\x88\',\n        31 =>  \'\xd9\x87\',\n        32 =>  \'\xdb\x8c\',\n    ];\n\n    if(substr($item1,0,2) == substr($item2,0,2))\n        return persianSort(substr($item1,2), substr($item2,2));\n    return array_search( substr($item1,0,2), $persian_characters) < array_search( substr($item2,0,2), $persian_characters) ? -1: 1;\n}\n\n$states = [\'\xda\xaf\xdb\x8c\xd9\x84\xd8\xa7\xd9\x86\', \'\xda\xaf\xd8\xb1\xda\xaf\xd8\xa7\xd9\x86\', \'\xdb\x8c\xd8\xb2\xd8\xaf\', \'\xd8\xb3\xd9\x85\xd9\x86\xd8\xa7\xd9\x86\', \'\xd8\xaa\xd9\x87\xd8\xb1\xd8\xa7\xd9\x86\', \'\xd8\xa7\xd8\xb1\xd8\xaf\xd8\xa8\xdb\x8c\xd9\x84\', \'\xda\xa9\xd8\xb1\xd9\x85\xd8\xa7\xd9\x86\', \'\xda\x86\xd9\x87\xd8\xa7\xd8\xb1 \xd9\x85\xd8\xad\xd8\xa7\xd9\x84 \xd8\xa8\xd8\xae\xd8\xaa\xdb\x8c\xd8\xa7\xd8\xb1\xdb\x8c\', \'\xd9\x85\xd8\xb4\xd9\x87\xd8\xaf\', \'\xd8\xa7\xd8\xb5\xd9\x81\xd9\x87\xd8\xa7\xd9\x86\', \'\xd9\x82\xd9\x85\', \'\xd8\xa2\xd8\xb3\xd8\xaa\xd8\xa7\xd8\xb1\xd8\xa7\'];\n\nusort($states, "persianSort");\n\nprint_r($states);\n
Run Code Online (Sandbox Code Playgroud)\n\n

上面的代码对伊朗省份名称的无序数组进行排序。上述代码的输出如下:

\n\n
Array\n(\n    [0] => \xd8\xa7\xd8\xb1\xd8\xaf\xd8\xa8\xdb\x8c\xd9\x84\n    [1] => \xd8\xa7\xd8\xb5\xd9\x81\xd9\x87\xd8\xa7\xd9\x86\n    [2] => \xd8\xaa\xd9\x87\xd8\xb1\xd8\xa7\xd9\x86\n    [3] => \xda\x86\xd9\x87\xd8\xa7\xd8\xb1 \xd9\x85\xd8\xad\xd8\xa7\xd9\x84 \xd8\xa8\xd8\xae\xd8\xaa\xdb\x8c\xd8\xa7\xd8\xb1\xdb\x8c\n    [4] => \xd8\xb3\xd9\x85\xd9\x86\xd8\xa7\xd9\x86\n    [5] => \xd9\x82\xd9\x85\n    [6] => \xda\xa9\xd8\xb1\xd9\x85\xd8\xa7\xd9\x86\n    [7] => \xda\xaf\xd8\xb1\xda\xaf\xd8\xa7\xd9\x86\n    [8] => \xda\xaf\xdb\x8c\xd9\x84\xd8\xa7\xd9\x86\n    [9] => \xd9\x85\xd8\xb4\xd9\x87\xd8\xaf\n    [10] => \xdb\x8c\xd8\xb2\xd8\xaf\n)\n
Run Code Online (Sandbox Code Playgroud)\n