如何使用array_walk在PHP中对三维数组进行排序?

时间:2015-07-16 00:02:43

标签: php arrays multidimensional-array

我有以下数组:

Array
(
    [1] => Array
        (
            [0] => Array
                (
                    [class] => Advanced Hip Hop Ages 10+
                    [session] => 0
                    [start] => 1436902200
                    [end] => 1436905800
                    [capacity] => 
                    [students] => 1
                )

            [1] => Array
                (
                    [class] => Intermediate Hip Hop Ages 9+
                    [session] => 0
                    [start] => 1436899500
                    [end] => 1436902200
                    [capacity] => 
                    [students] => 1
                )

            [2] => Array
                (
                    [class] => Beginning Pointe Ages 10+
                    [session] => 0
                    [start] => 1436896800
                    [end] => 1436899500
                    [capacity] => 
                    [students] => 1
                )

            [3] => Array
                (
                    [class] => Int/Adv Ballet  Ages 10+
                    [session] => 0
                    [start] => 1436889600
                    [end] => 1436896800
                    [capacity] => 15
                    [students] => 1
                )

            [4] => Array
                (
                    [class] => Beginning Ballet 8+ year olds
                    [session] => 0
                    [start] => 1436884200
                    [end] => 1436891400
                    [capacity] => 15
                    [students] => 1
                )

        )

    [2] => Array
        (
            [0] => Array
                (
                    [class] => Intermediate Technique/Progressions Ages 9+
                    [session] => 0
                    [start] => 1436899500
                    [end] => 1436904900
                    [capacity] => 
                    [students] => 1
                )

            [1] => Array
                (
                    [class] => Int/Adv Tap Ages 9+
                    [session] => 0
                    [start] => 1436895900
                    [end] => 1436899500
                    [capacity] => 
                    [students] => 1
                )

            [2] => Array
                (
                    [class] => Beginning Jazz/Contemporary Technique Ages 8+
                    [session] => 0
                    [start] => 1436887800
                    [end] => 1436893200
                    [capacity] => 
                    [students] => 1
                )

        )

    [3] => Array
        (
            [0] => Array
                (
                    [class] => Int/Adv Jazz 9+
                    [session] => 0
                    [start] => 1436893200
                    [end] => 1436898600
                    [capacity] => 
                    [students] => 1
                )

            [1] => Array
                (
                    [class] => Int/Adv Ballet Barre Ages 9+
                    [session] => 0
                    [start] => 1436886000
                    [end] => 1436889600
                    [capacity] => 
                    [students] => 1
                )

        )

)

我想按照开始时间对数组的第三级(类)进行排序。我已经尝试了一些不同的解决方案,这里提出了两个级别的数组,但没有用。

我最近的尝试是:

array_walk($schedule, 'walk_cmp');

function walk_cmp($array, $key){
    usort($array, function($a, $b) { 
      return ($a['start'] > $b['start']) ? -1: 1;
    });
}

我已确认排序在walk_cmp内有效,但对数组的更改不会反映在主数组中。

我觉得我必须遗漏一些明显的东西,但我在这里。请记住,这是一个动态的示例阵列。它将始终具有此结构,但第二个(日)和第三个(类)数组中的元素数量将有所不同。

2 个答案:

答案 0 :(得分:3)

您的尝试看起来很好,而且您也非常接近解决方案!

您的主要问题是,您将函数中的数组排序为局部变量。所以你的原始数组不会改变。你必须传递数组by reference.所以你的代码看起来像这样:

array_walk($schedule, "walk_cmp");

function walk_cmp(&$array, $key) {
                //^ See here
    uasort($array, function($a, $b) { 
        if($a['start'] == $b['start']) //If they are the same, return 0
            return 0;
        return ($a['start'] > $b['start']) ? -1 : 1;
    });

}

答案 1 :(得分:0)

有几种简洁现代的方法可以做到这一点:

  1. array_walk()array_multisort()array_column():(Demo

    array_walk($array, function(&$v) {
        array_multisort(array_column($v, 'start'), $v);
    });
    

    这会在迭代数组的第一级时通过引用进行修改,然后根据第三级中的目标列对第二级进行排序。 array_multisort()也会通过引用进行修改。

  2. array_walk()usort()和三向比较运算符(正式命名为“太空飞船运算符”)(Demo

    array_walk($array, function(&$a1) {
        usort($a1, function($a2, $b2) {
            return $a2['start'] <=> $b2['start'];
        });
    });
    

    从PHP7.4 起,箭头函数语法可用于减少总体语法。 (Demo

    array_walk($array, function(&$a1) {
        usort($a1, fn($a2, $b2) => $a2['start'] <=> $b2['start']);
    });
    

    您甚至可以简化array_walk()语法以形成单线:(Demo

    array_walk($array, fn(&$a1) => usort($a1, fn($a2, $b2) => $a2['start'] <=> $b2['start']));
    // array_walk silently ignores the data returned by the "arrow"