2012-04-03 77 views
0

我有一种情况,我已经获取并操纵SQL数据到数组和树中。我试图不惜一切代价避免递归,因为它已经让我陷入了过去。从父列表中获取儿童列表,而无需在PHP中递归

我有一个Parent_IDs的元素数组,我想能够获得他们的所有子女和子女的列表。它不应该像从另一种方式(从一个数组到一个嵌套树)一样复杂,我没有使用引用问题得到,但由于某种原因,我脑冻结...

任何帮助表示赞赏。

我有两种可能的格式的数据,因为我已经操纵它。哪个最适合输入可以使用。这是两个阵列的结构(的print_r)我有:

Array 
(
    [202735] => Array 
     (
      [ID] => 202735 
      [text] => aaafdf 
      [Parent] => 
     ) 

    [202737] => Array 
     (
      [ID] => 202737 
      [text] => Filho 2 
      [Parent] => 202735 
     ) 

    [202733] => Array 
     (
      [ID] => 202733 
      [text] => Neto 1 
      [Parent] => 202731 
     ) 

    [202739] => Array 
     (
      [ID] => 202739 
      [text] => Neto 2 
      [Parent] => 202737 
     ) 

) 

Array 
(
    [0] => Array 
     (
      [ID] => 202735 
      [text] => aaafdf 
      [Parent] => 
      [children] => Array 
       (
        [0] => Array 
         (
          [ID] => 202737 
          [text] => Filho 2 
          [Parent] => 202735 
          [children] => Array 
           (
            [0] => Array 
             (
              [ID] => 202739 
              [text] => Neto 2 
              [Parent] => 202737 
             ) 

           ) 

         ) 

       ) 

     ) 

    [1] => Array 
     (
      [ID] => 202733 
      [text] => Neto 1 
      [Parent] => 202731 
     ) 

) 
格式

所需的输出: (第一级父=>的子孙后代)

array(202731=>array(202735)); 
array(202735=>array(202737,202739)); 

或类似的...理想情况下,我会把它包装在像ListChildren($ InitialParent)这样的函数中,然后返回所有的孩子......调用ListChildren(0)或(null)会列出所有elem已废除和所有字幕...

OBS(附加的数组元素可以为这个工作的目的被忽略):在阵列中的一些数据丢失...即上述202735的类别,这将是202731,但那仅仅是因为我限制了我复制的数据......基本上,我可以使用父ID或平面数组,或嵌套子数组作为源的“树”数组。

回答

2

我结束了这一点。感谢您的帮助,最后我回到了递归代码。我会监视它的性能,但我想只是在PHP层,它不会是一个问题。当我在一个具有递归函数的数据库调用的项目中进行维护时,我的经历很糟糕......随着使用量的增长,递归函数的使用量呈指数增长,数据库调用的数量增加到了数以百计...

反正:

function __GetChildrenRec($Lista, $Categoria){ 
     // Return false if $initialParent doesn't exist 
     if ($Categoria == 0) $Categoria = ""; 
     if (!isset($Lista[$Categoria])) return FALSE; 

     // Loop data and assign children by reference 
     foreach ($Lista as $CategAtual) { 
      if ($CategAtual[Parent] == $Categoria) { 
       $Filhos[] = $CategAtual[ID]; 
       $Filhos = array_merge((array)$Filhos,(array)self::__GetChildrenRec($Lista, $CategAtual[ID])); 
      } 
     } 

     // Return the data 
     return is_array($Filhos) ? $Filhos : array(); 
    } 
+0

祝贺修复!如果可以,请确保将答案标记为“已接受”,以便其他人可以从您的成功中学习。干杯〜 – 2012-04-04 15:50:21

+0

Thks ...我试过了,但需要等到明天才能做到...明天就做... – RVN 2012-04-04 19:24:48

1

真的没有理由避免递归,除非它会导致您的真正性能问题。递归是大多数开发人员在查看这种性质的问题时可能会试图解决这些问题,而使用其他方法会伤害可维护性,因为您的代码正在做某些需要稍后维护您的代码的人不期望的事情。

一般来说,展开递归意味着管理一个堆栈。递归是一种让你使用的语言为你管理堆栈的方法,如果你不使用递归,那么你需要在你的函数中自己操作一个堆栈。这样做的最简单方法是使用array_push和array_pop,PHP中内置的函数使您可以将数组用作堆栈。

与简单使用递归相比,基于堆栈的方法相当复杂,如果递归给你带来问题,那么手动维护堆栈肯定会。有一定的好处,但老实说,我建议你试着找出递归,因为它确实更容易处理,虽然它不像自己管理堆栈那样性能高,但可能会导致性能下降不会成为代码中的瓶颈,因为PHP脚本中的瓶颈往往是PHP与外部世界(数据库,文件,网络连接等)的接口。

+1

...除了这个问题可以很容易地解决与参考。尽管确实没有理由避免一般的递归。 – DaveRandom 2012-04-03 15:43:15

+0

是的,好点。没有想到,直到我看到其他答案。 – GordonM 2012-04-03 17:15:00

0

使用第一阵列格式:

function list_children ($array, $initialParent) { 

    // Return false if $initialParent doesn't exist 
    if (!isset($array[$initialParent])) return FALSE; 

    // Loop data and assign children by reference 
    foreach ($array as &$item) { 
    if (isset($array[$item['parent']])) { 
     if (!isset($array[$item['parent']]['children'])) $array[$item['parent']]['children'] = array(); 
     $array[$item['parent']]['children'][] = &$item; 
    } 
    } 

    // Return the data 
    return (isset($array[$initialParent]['children'])) ? $array[$initialParent]['children'] : array(); 

} 

这样做是基本上创建从第一第二阵列,但它通过引用做它 - 因此初始母仍然可以发现由它的ID,和回。返回儿童数组,如果没有子女,则为空array();如果$initialParent不存在,则返回FALSE

+0

这类作品让我没有比以前更进一步,因为它不会输出“扁平”数组......它的嵌套数组非常类似于我的第二个数组示例......感谢努力:/ – RVN 2012-04-03 16:08:15

+0

你想如何平面阵列?你的意思是你只想要一个给定父亲的所有孩子的ID的一维数组?这或多或少是不可能的,没有递归... – DaveRandom 2012-04-03 16:29:30

+0

是的,一个阵列与所有的孩子和孙子们......我想这就是为什么我的大脑放出来......大声笑......或多或少的不可能解决它为我然后,我会做一个小的递归,然后...我猜,因为数据库调用是不是递归它不应该是一个问题。无论如何谢谢 – RVN 2012-04-03 18:33:31