2017-04-25 4 views
1

この配列はアルファベット順で並べ替える必要があります( "e"は "é"の直前に、 "a"は " à "など)。配列は、JSONファイルから読み込まれ、デコードされ、編成されます(または、そうでなければなりません)。私の唯一の問題は、アクセントを持つすべての文字が最後に置かれていることです。ここに私のコードの例です:Strcoll UTF-8ソート - PHP

$myArray = [ 
    {"myKey":"Aaa","values":[1,1,1,1,1,1,1]}, 
    {"myKey":"Test01","values":[1,1,1,1,1,1,1]}, 
    {"myKey":"Test02","values":[1,1,1,1,1,1,1]}, 
    {"myKey":"BBB","values":[1,1,1,1,1,1,1]}, 
    {"myKey":"Écha","values":[1,1,1,1,1,1,1]} 
] 

setlocale(LC_COLLATE, 'fr_CA.utf8'); 

usort($myArray, function($a, $b){ 
    return strcoll($a["myKey"], $b["myKey"]); 
}); 

$myNewFile = json_encode($myArray,JSON_NUMERIC_CHECK|JSON_UNESCAPED_UNICODE); 
echo $myNewFile; 

エコーが得られます。

[ 
    {"myKey":"Aaa","values":[1,1,1,1,1,1,1]}, 
    {"myKey":"BBB","values":[1,1,1,1,1,1,1]}, 
    {"myKey":"Test01","values":[1,1,1,1,1,1,1]}, 
    {"myKey":"Test02","values":[1,1,1,1,1,1,1]}, 
    {"myKey":"Écha","values":[1,1,1,1,1,1,1]} 
] 

を、それがあるべきとき:

[ 
    {"myKey":"Aaa","values":[1,1,1,1,1,1,1]}, 
    {"myKey":"BBB","values":[1,1,1,1,1,1,1]}, 
    {"myKey":"Écha","values":[1,1,1,1,1,1,1]}, 
    {"myKey":"Test01","values":[1,1,1,1,1,1,1]}, 
    {"myKey":"Test02","values":[1,1,1,1,1,1,1]} 
] 

私は自分のベストを試みたとして、私はまた、次のことを試してみましたこの課題に関する複数の投稿を含む既存のソリューションを見つける:

$collator = new Collator('fr_CA.utf8'); 
$collator->sort($myArray); 
(私はPHP 7+上だけど、私は絶望的だので、必要ありません)

usort($myArray, function($a, $b) { 
    return $a['myKey'] <=> $b['myKey']; 
}); 

私もしました(私はPHPによ以来7+)

usort($myArray["Ingrédients"], 'custom_sort'); 

function custom_sort(($a, $b){ 
    return strcoll($a["Ingrédients"], $b["Ingrédients"]); 
}); 

とこのよう

'fr_CA.utf8', 'fr_FR.utf8', 'fr_CA', 'fr_FR' 

としての私のsetlocaleのための使用異なった国コードは、これらの方法のそれぞれは、私がこれまで見てきたすべての記事のみんなのために働くように見えるが、彼らは非常に時代遅れです。それらはすべて、アクセントのソートとは別に動作しますので、メソッドに関係なく、私は同じ結果を得ています。それが役立つなら、サーバはPHP 7.1.1上にあります。私は本当に困惑しています。誰かがこれを修正したことを知っていたり、テーブルに持っていくための啓発があれば、本当に素晴らしいことになります。

ありがとうございます!

EDIT/SOLUTION:

それはまだusortだが、アクセント付き文字のための追加の置換を持ちます。これにはフランス語の文字しか含まれていませんが、あなたはその考えを得ています。

usort($myArray, function($a, $b) { 
    $translit = array('Á'=>'A','À'=>'A','Â'=>'A','Ä'=>'A','Ã'=>'A','Å'=>'A','Ç'=>'C','É'=>'E','È'=>'E','Ê'=>'E','Ë'=>'E','Í'=>'I','Ï'=>'I','Î'=>'I','Ì'=>'I','Ñ'=>'N','Ó'=>'O','Ò'=>'O','Ô'=>'O','Ö'=>'O','Õ'=>'O','Ú'=>'U','Ù'=>'U','Û'=>'U','Ü'=>'U','Ý'=>'Y','á'=>'a','à'=>'a','â'=>'a','ä'=>'a','ã'=>'a','å'=>'a','ç'=>'c','é'=>'e','è'=>'e','ê'=>'e','ë'=>'e','í'=>'i','ì'=>'i','î'=>'i','ï'=>'i','ñ'=>'n','ó'=>'o','ò'=>'o','ô'=>'o','ö'=>'o','õ'=>'o','ú'=>'u','ù'=>'u','û'=>'u','ü'=>'u','ý'=>'y','ÿ'=>'y'); 
    $at = strtr($a['myKey'], $translit); 
    $bt = strtr($b['myKey'], $translit); 
    return strcoll($at, $bt); 
}); 

これは将来的に役立ちます。

答えて

1

あなたが持っている問題は、文字の価値によるものです。 strcollは、使用している文字セットの文字の値に基づいて文字列を比較します。私はあなたがutf-8か非常によく似た何かを使っていると仮定しようとしています。値については、UTF-8を参照してください。アクセント記号付きのeの値がZよりもはるかに大きいことに注意してください。だからあなたはこの問題を抱えています。これを修正するには、アクセントのついた文字の特別な場合を追加する必要があります。それ以外の場合は通常のソートは機能しません。だから、基本的には、fを通常とするようなアクセント記号でeを置くあなた自身のcompare関数を作成します。

+0

実際、多くの意味があります。ありがとうございます。私はそれに右に行くよ! –

+0

いいえ、問題です。また、あなたはここで新しいようですので、https://stackoverflow.com/help/someone-answersを参照してください。 –

+0

興味のある人のために、そして今後の参考としてOPを更新します。 私の置き換え機能が実際に値の代わりにテキストを置き換えた後、2012年のフランス語フォーラムに関する多くの研究の後で解決策を見つけました。 –