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函数适用于波斯语字符?
我编写了以下函数来为任何给定字符返回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可以正常工作。
以及获取您可以使用的可用区域设置
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)
我知道这个问题已经很老了,但这可能仍然可以帮助新来的人寻找这个问题的答案。
要按波斯语字符对数组进行排序,首先请注意 Unicode 标准中的某些字符未正确对齐。\n在这种情况下,我的建议是创建一个常规的波斯语字符数组,并根据该数组排列主题数组。\nfor例子:
\n\nfunction 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);\nRun Code Online (Sandbox Code Playgroud)\n\n上面的代码对伊朗省份名称的无序数组进行排序。上述代码的输出如下:
\n\nArray\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)\nRun Code Online (Sandbox Code Playgroud)\n