-4

我有一个存储 id > parent 的数组

我想要做的是使用 PHP 中的 uasort 函数对这个数组进行排序,将所有孩子放在他们的父母之下

所以如果我有

ID>>PARENT
1 >> 0
2 >> 0
3 >> 1
4 >> 1
5 >> 0
6 >> 2
7 >> 6
8 >> 6
9 >> 2

那么我需要像这样返回结果

ID
1
3
4
2
6
7
8
9

我的数组是这样的

Array (
     [0] => Array
        (
            [ID] => 1
            [PARENT] => 0
        ) 

     [1] => Array
        (
            [ID] => 2
            [PARENT] => 0
        ) 

     [2] => Array
        (
            [ID] => 3
            [PARENT] => 1
        ) 

     [3] => Array
        (
            [ID] => 4
            [PARENT] => 1
        ) 

     [4] => Array
        (
            [ID] => 5
            [PARENT] => 0
        ) 
     [5] => Array
        (
            [ID] => 6
            [PARENT] => 2
        ) 

     [6] => Array
        (
            [ID] =>7
            [PARENT] => 6
        ) 

     [7] => Array
        (
            [ID] =>8
            [PARENT] => 6
        ) 

     [8] => Array
        (
            [ID] =>9
            [PARENT] => 9
        ) 
)

这就是我所做的

uasort($survey, 'cmp');

print_r($survey);


function cmp($a, $b) {
    if ($a['parent_id'] == $b['parent_id']) {
        return 0;
    }
    return ($a['parent_id'] < $b['parent_id']) ? -1 : 1;
}

此代码首先对所有父母进行排序,然后将孩子排在父母之后,而不是在他们之下。

有人可以帮我解决这个问题吗?

4

2 回答 2

3

uasort()和朋友在这里不太适合目的:假设您想将父母 N 的最后一个孩子与下一个父母 N+1 进行比较 - 孩子应该比较小。如果同一个孩子有父母 N+1,则需要比较大。这是可行的,只要你只有一个级别,但如果你有更多,它就会变得很糟糕。

我建议您使用另一种方法:

  • 第 1 步:按父项将条目分组到数组数组中
  • 第 2 步:单独对子数组进行排序
  • 第 3 步:通过递归展平结构:
    • 从当前父 id 0 和一个空的 final 开始
    • 重复
      • 将具有当前父 id 的数组的第一行移动到最终数组的末尾
      • 如果没有可用,返回
      • 以该行的 id 作为当前父 id 进行递归

编辑

根据要求,一些代码:这适用于我的示例。

请注意,您的示例似乎有点牵强:您想要的输出缺少 ID 5,虽然大多数根节点使用 0 作为父节点,但 ID 9 使用 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);
?>
于 2013-07-03T19:21:10.690 回答
0

循环数组并构建排序版本。

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

使用您的示例(并更正您的信息中的不匹配),我得到以下信息。

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
                )
        )
)
于 2013-07-03T20:03:42.413 回答