问题描述:

This question is an exact duplicate of:

  • How to sort a multi array in PHP with a Parent/Child Relationship? [closed]

网友答案:

uasort() and friends are not quite fit for purpouse here: Assume you want to compare the last child of parent N with the next parent N+1 - the child should compare as smaller. If the same child had parent N+1, it would need to compare bigger. This is doable, as long as you have only one level, but it gets qugly, if you have more.

I recommend you use another approach:

  • Step 1: Group entries into an array of arrays by parent
  • Step 2: Sort the sub-arrays individually
  • Step 3: Flatten the structure by recursion:
    • start with current parent id 0 and an empty final
    • repeat
      • move the first row of the array with the current parent id to the end of the final array
      • if none available, return
      • recurse with the id of this row as the current parent id

Edit

Some code, as requested: This works for me with your example.

Please be aware, that your example seems a bit stretchy: You desired output lacks the ID 5, and while most root nodes use 0 as a parent, ID 9 uses ID==PARENT.

<?php
function flatten($parentid, &$parents, &$final) {
  if (!isset($parents[$parentid])) return;
  $children=$parents[$parentid];
  unset($parents[$parentid]);

  //repeat
  while (true) {
    //move the first row of the array with the current parent id to the end of the final array
    $child=array_shift($children);

    //if none available, return
    if (!$child) break;
    $final[]=$child;

    //recurse with the id of this row as the current parent id
    flatten($child['ID'],$parents,$final);
  }
}

//Step 1: Group entries into an array of arrays by parent
//In your input, both PARENT==ID and PARENT==0 are used for root nodes
$parents=array();
foreach ($input as $item) {
  $parent=$item['PARENT'];
  if ($parent==$item['ID']) $parent=0;
  if (isset($parents[$parent])) $parents[$parent][$item['ID']]=$item;
  else $parents[$parent]=array($item['ID']=>$item);
}

//Step 2: Sort the sub-arrays individually
foreach ($parents as $item) ksort($item);

//Step 3: Flatten the structure by recursion:
//start with current parent id 0 and an empty final
$final=array();
flatten(0, $parents, $final);

//Done
print_r($final);
?>
网友答案:

Loop the array and build a sorted version.

$arr2 = array();
    foreach ( $arr as $k => $v ) {
        if ( $v['PARENT'] > 0 ) {
            $arr2[$v['PARENT']][$k] = $v;   
        }
    }
ksort($arr2);

Using your example (and correcting the mismatch in your info), I get the following.

Array
(
    [1] => Array
        (
            [3] => Array
                (
                    [ID] => 3
                    [PARENT] => 1
                )
            [4] => Array
                (
                    [ID] => 4
                    [PARENT] => 1
                )
        )
    [2] => Array
        (
            [6] => Array
                (
                    [ID] => 6
                    [PARENT] => 2
                )
            [9] => Array
                (
                    [ID] => 9
                    [PARENT] => 2
                )
        )
    [6] => Array
        (
            [7] => Array
                (
                    [ID] => 7
                    [PARENT] => 6
                )

            [8] => Array
                (
                    [ID] => 8
                    [PARENT] => 6
                )
        )
)
相关阅读:
Top