使用usort自定义整理与PHP

时间:2017-01-11 23:15:30

标签: php usort

我正在尝试按自定义字母排序数组(国际名称,没有任何Collat​​or语言环境将它们按照我想要的顺序排列)。

我从here窃取了一些代码并且有。

 function compare_by_alphabet($str1, $str2){
     $alphabet = "AaÀàÁáÂâÅåÃãÄäÆæBbCcÇçDdÐðEeÈèÉéÊêËëFfGgHhIiÌìÍíÎîÏïJjKkLlMmNnÑñOoÒòÓóÔôÕõÖöØøPpQqRrSsߊšTtUuÙùÚúÛûÜüVvWwXxYyŸÿÝýZzŽžÞþ0123456789";
     $l1 = strlen($str1);
     $l2 = strlen($str2);
     $c = min($l1, $l2);

     for ($i = 0; $i < $c; $i++)
     {
         $s1 = substr($str1, $i, 1);
         $s2 = substr($str2, $i, 1);
         if ($s1===$s2) continue;
         $i1 = strpos($alphabet, $s1);
         if ($i1===false) continue;
         $i2 = strpos($alphabet, $s2);
         if ($i2===false) continue;
         if ($i2===$i1) continue;
         if ($i1 < $i2) return -1;
         else return 1;
     }
     if ($l1 < $l2) return -1;
     elseif ($l1 > $l2) return 1;
     return 0;
 }

当我尝试

$names=["Schön","Åsberg","Zierer","Ås","Žižek","Schon","Asber"];
usort($names, 'compare_by_alphabet');

我得到["Asber","Ås","Åsberg","Schön","Schon","Žižek","Zierer"] - 两个Schon的错误就在身边,Žižek和Zierer也是如此。

我在这里遗漏了一些东西。有人可以解释为什么这不符合预期,请?或者我如何解决它?

1 个答案:

答案 0 :(得分:0)

标准PHP字符串函数不是多字节兼容的。在您的示例中,字符串和字母表包含多字节字符(大多数现代php编辑器将使用utf-8作为默认值encoding)。例如,À实际上由utf-8中的2个字节表示。

运行以下内容以验证:

php > echo strlen("À");
2

使用multibyte string函数解决问题。

应用此代码后,代码为:

function compare_by_alphabet($str1, $str2) {

    $alphabet = "AaÀàÁáÂâÅåÃãÄäÆæBbCcÇçDdÐðEeÈèÉéÊêËëFfGgHhIiÌìÍíÎîÏïJjKkLlMmNnÑñOoÒòÓóÔôÕõÖöØøPpQqRrSsߊšTtUuÙùÚúÛûÜüVvWwXxYyŸÿÝýZzŽžÞþ0123456789";
    $l1 = mb_strlen($str1);
    $l2 = mb_strlen($str2);
    $c = min($l1, $l2);

    for ($i = 0; $i < $c; $i++)
    {
        $s1 = mb_substr($str1, $i, 1);
        $s2 = mb_substr($str2, $i, 1);
        if ($s1===$s2) continue;
        $i1 = mb_strpos($alphabet, $s1);
        if ($i1===false) continue;
        $i2 = mb_strpos($alphabet, $s2);
        if ($i2===false) continue;


    if ($i2===$i1) continue;
        if ($i1 < $i2) return -1;
        else return 1;
    }
    if ($l1 < $l2) return -1;
    elseif ($l1 > $l2) return 1;
    return 0;
}

$names=["Schön","Åsberg","Zierer","Ås","Žižek","Schon","Asber"];
usort($names, 'compare_by_alphabet');
var_dump($names);

和结果

array(7) {
  [0]=>string(5) "Asber"
  [1]=>string(3) "Ås"
  [2]=>string(7) "Åsberg"
  [3]=>string(5) "Schon"
  [4]=>string(6) "Schön"
  [5]=>string(6) "Zierer"
  [6]=>string(7) "Žižek"
}