2017-01-11 20 views
0

私はカスタムアルファベット(国際的な名前で配列をソートしようとしていますが、Collat​​orのロケールはまったく同じ順序で並べていません)。usortを使用したPHPとのカスタム照合

私はhereからいくつかのコードを盗まれました。ジジェクとZiererているように、2つのショーンさんが間違っては周りだったです - 私は

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

をしようとすると

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

は私が["Asber","Ås","Åsberg","Schön","Schon","Žižek","Zierer"]を取得します。

ここに何か不足しています。誰かがこれが期待どおりに動作しない理由を説明できますか?または私はそれを修正することができますか?

答えて

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ŽžÞþ"; 
    $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" 
} 
+0

私はそれを知りませんでした!ありがとう、ありがとう。 – Richie

関連する問題