16

I have an array of this form:

Array
(
    [first_level] => Array
        (
            [dir_3] => Array
                (
                    [subdir_1] => Array
                        (
                            [file_2.mp4] => stdClass Object
                                (
                                    [name] => file_2.mp4
                                )

                            [file_1.mp4] => stdClass Object
                                (
                                    [name] => file_1.mp4
                                )

                        )
                )
            [dir_1] => Array
                (
                    [subdir_2] => Array
                        (
                            [file_6.mp4] => stdClass Object
                                (
                                    [name] => file_6.mp4
                                )
                            [file_9.mp4] => stdClass Object
                                (
                                    [name] => file_9.mp4
                                )
                            [file_7.mp4] => stdClass Object
                                (
                                    [name] => file_7.mp4
                                )
                        )
                    [subdir_1] => Array
                        (
                            [file_8] => stdClass Object
                                (
                                    [name] => file_8.mp4
                                )

                        )
        )
    )
)

I need to order it like this:

Array
(
    [first_level] => Array
        (
            [dir_1] => Array
                (
                    [subdir_1] => Array
                        (
                            [file_8] => stdClass Object
                                (
                                    [name] => file_8.mp4
                                )
                        )
                    [subdir_2] => Array
                        (
                            [file_6.mp4] => stdClass Object
                                (
                                    [name] => file_6.mp4
                                )
                            [file_7.mp4] => stdClass Object
                                (
                                    [name] => file_7.mp4
                                )
                            [file_9.mp4] => stdClass Object
                                (
                                    [name] => file_9.mp4
                                )
                        )
        )
        [dir_3] => Array
                (
                    [subdir_1] => Array
                        (
                            [file_1.mp4] => stdClass Object
                                (
                                    [name] => file_1.mp4
                                )

                            [file_2.mp4] => stdClass Object
                                (
                                    [name] => file_2.mp4
                                )

                        )
                )
    )
)

I browsed through other similar questions, and I've been trying to solve it with usort but I couldn't get my head around it. :S

Any idea?

4v4l0n42
  • 173
  • 1
  • 1
  • 6

3 Answers3

34

Use a recursive function:

// Note this method returns a boolean and not the array
function recur_ksort(&$array) {
   foreach ($array as &$value) {
      if (is_array($value)) recur_ksort($value);
   }
   return ksort($array);
}
maksim
  • 804
  • 2
  • 9
  • 16
netcoder
  • 64,266
  • 17
  • 119
  • 142
  • Of course! That was easy... shame on me for not seeing it on the spot :P Thanks, works like a charm. – 4v4l0n42 Dec 21 '10 at 16:29
  • 2
    This answer made me spot a silly mistake in my own code. :o I came up with some very similar code on my own, but I forgot the `&` before `&$value`, so I was breaking my head why only my first level was getting sorted. Thanks for unwittingly helping me. ;) – Byson Dec 04 '14 at 13:05
  • 3
    Some people may not now, so it's worth mentioning that ksort (and asort and similar functions) modify the original array and instead of returning a sorted copy of it they return a boolean. Thus, this function will return a boolean instead of the array itself. – DiegoDD Mar 03 '15 at 16:26
  • 1
    As noted in other answers and comments, ksort is in-place, so you don't want the return value. – Ariel Allon Jul 01 '16 at 14:30
4
function ksort_recursive(&$array)
{
    if (is_array($array)) {
        ksort($array);
        array_walk($array, 'ksort_recursive');
    }
}

As noted in their comments, answers with return ksort() are incorrect as ksort() returns a success bool.

Note that this function does not throw "Warning: ksort() expects parameter 1 to be array" when given a non-array - this matches my requirements but perhaps not yours.

Deebster
  • 2,798
  • 1
  • 26
  • 25
4

You need to use ksort.

// Not tested ...    
function recursive_ksort(&$array) {
    foreach ($array as $k => &$v) {
        if (is_array($v)) {
            recursive_ksort($v);
        }
    }
    return ksort($array);
}
ARIF MAHMUD RANA
  • 4,767
  • 3
  • 29
  • 51
Vincent Mimoun-Prat
  • 27,630
  • 15
  • 77
  • 123