私は同じ問題と戦ってきました。setlocale()をasort ($array ,SORT_LOCALE_STRING)と一緒に使用できます。これにより、ÅÄÖ 文字が最後に配置されます。残念ながら、それらは間違った順序になっています。PHP はそれらを ä、å、ö でソートします。北欧の言語 (少なくともスウェーデンのアルファベット) では、å、ä、ö のように並べ替えられます。多くのグーグル検索の後、PHP ネイティブ機能でこれを解決できなかったので、共有できると思われる独自の「パッチを適用した」並べ替えを作成しました。
私は計算速度を最適化したコードを書く専門家ではないので、このコードにはいくつかの改善点があると確信しています。それらを指摘していただければ幸いです。
ただし、この関数は、最初の文字だけでなく、文字列全体に基づいて配列をソートします。しかし、それが最も便利な方法だと思います。最初の文字以降をすべて無視したい場合は、これを変更できると確信しています。また、他の文字や他の並べ替え順序に適用するように変更することも非常に簡単です。楽しみ
function sort_nordic(&$array) {
uasort($array, 'nordic_cmp');
}
function nordic_cmp($a, $b) {
// If å, ä, and ö is missing from first string, just use PHP's native function
if (preg_match('/([å]|[ä]|[ö]|[Å]|[Ä]|[Ö])/', $a) == 0) {
return strcoll($a, $b);
}
// If å, ä, and ö is missing from second string, also use PHP's native function
if (preg_match('/([å]|[ä]|[ö]|[Å]|[Ä]|[Ö])/', $b) == 0) {
return strcoll($a, $b);
}
// Arriving here both the strings contains some characters we have too look out for
// First, create arrays from the strings so we can easily loop over the characters
// Comparison is made in lowercase
$a_arr = preg_split('//u', mb_strtolower($a), -1, PREG_SPLIT_NO_EMPTY);
$b_arr = preg_split('//u', mb_strtolower($b), -1, PREG_SPLIT_NO_EMPTY);
// Get the length of the shortest string
$end = min(mb_strlen($a), mb_strlen($b));
// Loop over the characters and compare them in pairs
for ($i = 0; $i < $end; $i++) {
// Check if character in the first string is one that we have to correct for
if (mb_stripos("åäö", $a_arr[$i]) !== false) {
// Computes the corrected return value. The first character "-" is just a
// nonsene placeholder to return 1 for "ä", 2 for "å" and 3 for "ö"
$r = mb_stripos("-åäö", $a_arr[$i]) - mb_stripos("-åäö", $b_arr[$i]);
if ($r != 0) {
return $r;
}
} else {
// If the character is not a character that we have to correct for
// the PHP native works fine
$r = strcoll($a_arr[$i], $b_arr[$i]);
if ($r != 0) {
return $r;
}
}
}
// Fallback: If so far there has been no call to return() then the
// strings are idenical up until the length of the shorter string.
// Then let the lengths of the strings determine the order
return mb_strlen($a) - mb_strlen($b);
}