PHP Group数组按字母顺序排列特定于语言的约定

时间:2013-03-17 12:43:22

标签: php arrays localization group-by sorting

我正在寻找一种智能解决方案,用扩展字符对字符串进行排序。它始终是使用过的语言的问题。我们以德语为例:A和Ä有时可以按照相同的字母(DIN 5007/1)进行排序,有时Ä可以按照事实上的“AE”(DIN 5007/2)进行排序。相比之下,在瑞典语中,Ä出现在字母表的末尾。

可以在Alphabetical order: Language-specific conventions找到各种语言的此类约定列表。

什么是最快的方法,对像DIN 5007/1这样的数组进行分组

$array = array
(
    0 => 'Agile',
    1 => 'Ágile',
    2 => 'Àgile',
    3 => 'Âgile',
    4 => 'Ägile',
    5 => 'Ãgile',
    6 => 'Test',
);

// Grouped Result:

Array
(
    'A' => array
    (
        [0] => Agile
        [1] => Àgile
        [2] => Ágile
        [3] => Âgile
        [4] => Ãgile
        [5] => Ägile
    ),
    'T' => array
    (
        [0] => Test
    )
)

1 个答案:

答案 0 :(得分:2)

我认为没有一种快速的方法可以对DIN 5007/1这样的阵列进行分组。至少我没有看到一个。

解决方案需要考虑两个方面:根据DIN 5007/1考虑排序的排序算法。将结果分组,以尊重由特殊字符引起的相似性。

排序

使用array_multisort()参数时,您可以设置SORT_LOCAL_STRING。请务必通过之前设置setlocal()来选择适当的区域设置信息(例如de_DE

// randomly sorted terms
$array = array(
    'Agile',
    'Ágile',
    'Test',
    'Âgile',
    'Ägile',
    'Ãgile',
    'Àgile',
);

setlocale(LC_ALL, '');
array_multisort($array, SORT_ASC, SORT_LOCALE_STRING);
print_r($array);

但这并不会导致你想要的结果。

Array
(
    [0] => Agile
    [1] => Test
    [2] => Àgile
    [3] => Ágile
    [4] => Âgile
    [5] => Ãgile
    [6] => Ägile
)

您必须深入了解可用的区域设置,也可以手动添加所有相关区域设置。

  

类别/区域设置名称可在»RFC 1766和»ISO 639中找到。 (source)

分组

使用预定义的组有一个well-working algorithm for grouping。这意味着您必须手动定义映射表(例如Ä = AÖ = O ...)。

或者您可以实施相似性检查,例如similar_text()levenshtein()

SQL作为替代方案?

在SQL中如何更有效地实现此问题需要进一步考虑。