Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting each level of a nested multidimensional PHP array

I have a multidimensional PHP array that I am using to generate a hierarchical UL tree. However, before displaying the UL tree, I would like to sort each level within the array alphabetically by the 'name' attribute. I am imagining a function that recursively checks each level, organizes it alphabetically, and moves on to the next level to sort that level. But I'm not sure how to do that. Any help would be appreciated!

My array:

Array ( 
 [0] => Array ( 
   [id] => 39348
   [parent] => 0
   [name] => Test 
   [children] => Array ( 
     [0] => Array ( 
       [id] => 41911 
       [parent] => 39348 
       [name] => Test2 
       [children] => Array ( 
         [0] => Array ( 
            [id] => 40929
            [parent] => 41911
            [name] => Test3 
            [children] => Array ( 
               [0] => Array (
                   [id] => 40779 
                   [parent] => 40929 
                   [name] => C 
               ) 
               [1] => Array (
                   [id] => 40780 
                   [parent] => 40929
                   [name] => A
               ) 
            ) 
         )
      ) 
   )

My attempt, which is moving the order around, but it is still not alphabetical. Note, the array($this,'sortByName') is required by CodeIgniter, which I am working in:

function recursive_sort($array) {
  usort($array, array($this,'sortByName'));
  foreach($array as $key => $value) {
    if(isset($value['children']) && !empty($value['children']) && is_array($value['children'])) {
      $array[$key]['children'] = $this->recursive_sort($value['children']);
    }
  }
  return $array;
}

function sortByName($a, $b){
    return $a->name - $b->name;
}

UPDATE: SOLUTION

function recursive_sort($array,$child='children') {
        usort($array,function($a,$b){
            return strcasecmp($a['name'], $b['name']);
        });
        foreach($array as $key => $value) {
            if(isset($value[$child]) && !empty($value[$child]) && is_array($value[$child])) {
              $array[$key][$child] = $this->recursive_sort($value[$child],$child);
            }
        }
        return $array;
    }
like image 222
skiindude22 Avatar asked Dec 29 '15 05:12

skiindude22


1 Answers

I typed up a an algorithmic way of thinking so you can implement the code yourself. Besides, I wouldn't want to take away all the fun away from you! :-)

If it isn't enough for you, check out this.

function example(element) {
    if (no children exist) return
    if (only one element exist on this level) 
        // if this code is reached, this element has children
        example(children element)
        return
    names = { array of all name attributes of all elements on this level }
    sort(names)
    [0] => names[0]
    [1] => names[1]
       .. and so on for however many elements there are
    return
like image 171
Austin Derrow-Pinion Avatar answered Oct 17 '22 12:10

Austin Derrow-Pinion