Strcoll UTF-8 排序 - PHP

Strcoll UTF-8 Sorting - PHP

所以我有这个数组需要按字母顺序排序,忽略重音符号(如 "e" 应该在“é”之前,而 "a" 后面应该跟它的变体,例如“à” “, 例如)。该数组从 JSON 文件中读取、解码、组织(或应该组织),然后编码回来(供员工添加对象)。我唯一的问题是每个带有重音的字母都放在最后。这是我的代码示例:

$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["Ingrédients"], 'custom_sort');

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

和(因为我在 PHP 7+)

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

我还为我的 setlocale 使用了不同的国家代码,例如

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

这些方法中的每一种似乎都适用于我目前看到的所有帖子中的每个人,但它们已经过时了。除了对重音进行排序之外,它们都有效,所以无论使用哪种方法,我得到的结果都是一样的。如果有帮助,服务器在 PHP 7.1.1 上。我真的很困惑,如果有人知道解决这个问题或者对 table.

有一些启发,那就太好了

谢谢!

编辑/解决方案:

它仍然是一个 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);
});

希望这对以后有所帮助!

好的,简而言之,您遇到的问题是由于角色的价值。 strcoll 根据您使用的字符集的字符值比较字符串。我将假设您使用的是 utf-8 或非常相似的东西。查看 UTF-8 的值,注意带有重音符号的 e 的值如何比 Z 高得多?这就是你遇到这个问题的原因。为了修复它,您必须为重音字符添加特殊情况,否则正常排序将不起作用。因此,基本上,创建您自己的比较函数,它将 e 与 f 通常所在的重音标记等等。