如何在保留树层次结构的同时按字母顺序排列数组?

时间:2012-12-29 23:04:16

标签: php arrays sorting recursion

我有2个未知长度/深度的数组,看起来像这样

[1] => Hand Tools
[2] => Power Tools
[4] =>  ╚═►Outdoor Tools
[6] =>    ╚═►dvjdg
[5] =>  ╚═►Indoor Tools
[7] =>    ╚═►blaha
[8] =>    ╚═►blahb
[3] => Garden Tools

[1] => 0
[2] => 0
[4] => 1
[6] => 2
[5] => 1
[7] => 2
[8] => 2
[3] => 0

两个数组都使用category id作为数组索引,第二个数组包含每个类别的深度。第一个数组用于生成HTML <select>输入,但我现在需要按字母顺序排列此数组,同时保持正确的类别层次结构。所以我需要得到这样的输出数组。

[3] => Garden Tools
[1] => Hand Tools
[2] => Power Tools
[5] =>  ╚═►Indoor Tools
[7] =>    ╚═►blaha
[8] =>    ╚═►blahb
[4] =>  ╚═►Outdoor Tools
[6] =>    ╚═►dvjdg

我该如何做到这一点?

1 个答案:

答案 0 :(得分:2)

考虑到$list是你的数组,你不能轻易地对它进行排序,因为每个“sub”元素都不包含它的父元素的信息(文本)。首先要添加这些信息:

  1. 获得关卡。
  2. 设置该级别的当前值。
  3. 删除更高级别。
  4. 将所有级别与未在文本中使用的字符合并在一起。
  5. 你有这个排序键。对所有列表条目执行此操作,您已获得所有排序键:

    $sortkeys = [];
    $levels   = [];
    foreach ($list as $index => $entry) {
        $level            = strspn($entry, ' ');
        $levels[$level]   = $entry;
        $sortkey          = implode('|', array_slice($levels, 0, $level + 1));
        $sortkeys[$index] = $sortkey;
    }
    

    此示例简化了获取级别信息。我每个级别都计算了一个空格。您可能有不同之处,并使用与strspn不同的功能。很可能你会使用你的第二个阵列。我懒得打字,所以我用这个功能做了。你可能只是:

    $level = $category_levels[$index];
    

    现在,您可以根据$list数组对$sortkeys数组进行排序。这可以通过PHP的array_multisort函数来完成。因为该函数会重新编号数字键,我们也会对键进行排序,然后在排序后进行组合以保留它们:

    $keys = array_keys($list);
    array_multisort($sortkeys, SORT_ASC, $list, $keys);
    
    print_r(array_combine($keys, $list));
    

    这给了你:

    Array
    (
        [3] => Garden Tools
        [1] => Hand Tools
        [2] => Power Tools
        [5] =>  ╚═►Indoor Tools
        [7] =>   ╚═►blaha
        [8] =>   ╚═►blahb
        [4] =>  ╚═►Outdoor Tools
        [6] =>   ╚═►dvjdg
    )
    

    观看正在运行的完整示例:Demo