2013-03-19 88 views
1

everyone!使用遞歸將純數組轉換爲多維數組

我被困在試圖寫一個遞歸函數。 =( 這是我的職責,正如我所料,會變成我的普通數組到多維一個

function BuildTree($src, $index=0) { 
    foreach ($src as $index=>$curentItem) { 
     $nextItem = (is_array($src[$index+1]))?$src[$index+1]:false; 
     unset($src[$index]); 
     if ($nextItem['d']==$curentItem['d']) $brunchArray[] = $curentItem['n']; 
     if ($nextItem['d']>$curentItem['d']) $brunchArray['childrens'] = BuildTree($src, $index); 
     if (!$nextItem || $nextItem['d']<$curentItem['d']) return $brunchArray; 
    } 
} 

輸入數組是這樣的:

$input = array (
array(
     'n' => 'Articles', 
     'd' => 0 
    ), 
array(
     'n' => 'Article 1', 
     'd' => 1 
    ), 
array(
     'n' => 'Books', 
     'd' => 0 
    ), 
array(
     'n' => 'Book 1', 
     'd' => 1 
    ), 
array(
     'n' => 'Book 2', 
     'd' => 1 
    ), 
array(
     'n' => 'Chapter 1', 
     'd' => 2 
    ), 
array(
     'n' => 'Chapter 2', 
     'd' => 2 
    ) 
); 

而且我希望它是轉換成這樣:!

array (
    array(
      'n' => 'Articles', 
      'd' => 0, 
      'childrens' => array (
       array(
         'n' => 'Article 1', 
         'd' => 1 
        ), 
      ) 
     ), 
    array(
      'n' => 'Books', 
      'd' => 0, 
      'childrens' => array (
       array(
         'n' => 'Book 1', 
         'd' => 1 
        ), 
       array(
         'n' => 'Book 2', 
         'd' => 1 
         'childrens' => array (
          array(
            'n' => 'Chapter 1', 
            'd' => 2 
           ), 
          array(
            'n' => 'Chapter 2', 
            'd' => 2 
           ) 
         ) 
        ) 
      ) 
     ) 
) 

我已經花了三個小時試圖解決這一=(任何幫助將高度讚賞

+0

以及您的程序應該猜出哪個項目其中一個孩子? – aram90 2013-03-19 10:32:24

+0

它們已按正確順序排列 – Vit 2013-03-19 10:35:31

+0

是否必須遞歸? – 2013-03-19 10:38:48

回答

0

使用相同的$input

$output = array(); 

function buildTree(&$input, &$output, &$current, $level = 0) { 
    if(!$input) 
     return; 
    $next = array_shift($input); 
    if($next['d'] == $level) { 
     $current[] = $next; 
     return buildTree($input, $output, $current, $level); 
    } else if($next['d'] == $level + 1) { 
     $current[count($current) - 1]['childrens'] = array($next); 
     return buildTree($input, $output, $current[count($current) - 1]['childrens'], $level + 1); 
    } else { 
     $output[] = $next; 
     return buildTree($input, $output, $output, 0); 
    } 
} 

buildTree($input, $output, $output); 

var_dump($output); 
+0

哇!而已! 非常感謝,你救了我的一天! =) – Vit 2013-03-19 11:04:42

+0

謝謝:D我喜歡解決這個問題!好問題:) – 2013-03-19 11:05:57

+0

@ aram90在其他地方發佈了「非遞歸」解決方案。它也很好。比較哪一個更快會很有趣。 – Vit 2013-03-19 11:14:51

1

這裏是不遞歸的解決方案:

function convert($arr) { 
    $stack = array(); 
    $output = array(); 
    $arr[] = array('d' => -1); // Dummy record at the end 
    for($i = 0; $i < count($arr); $i++) { 
     while(!empty($stack) && $stack[count($stack) - 1]['d'] > $arr[$i]['d']) { 
      $current_d = $stack[count($stack) - 1]['d']; 
      $children = array(); 
      while(!empty($stack) && $stack[count($stack) - 1]['d'] >= $current_d) { 
       $children[] = array_pop($stack); 
      } 
      $children = array_reverse($children); 
      if(empty($stack)) { 
       foreach($children as $child) { 
        $output[] = $child; 
       } 
      } else { 
       $stack[count($stack) - 1]['children'] = $children; 
      } 
     } 
     $stack[] = $arr[$i]; 
    } 
    return $output; 
} 

$input = array (
array(
     'n' => 'Articles', 
     'd' => 0 
    ), 
array(
     'n' => 'Article 1', 
     'd' => 1 
    ), 
array(
     'n' => 'Books', 
     'd' => 0 
    ), 
array(
     'n' => 'Book 1', 
     'd' => 1 
    ), 
array(
     'n' => 'Book 2', 
     'd' => 1 
    ), 
array(
     'n' => 'Chapter 1', 
     'd' => 2 
    ), 
array(
     'n' => 'Chapter 2', 
     'd' => 2 
    ) 
); 

var_dump(convert($input)); 
+0

酷!我很驚訝,可以這樣做,但你證明了它。 我會嘗試比較哪一個稍快一些。 – Vit 2013-03-19 11:11:11

+0

如何在本網站上將兩個答案都標記爲正確?可能嗎? – Vit 2013-03-19 11:12:09

+0

不幸的是,你不能,但你必須牢記你的問題:「我被困在試圖寫一個遞歸函數」:(剛投票答案,以傳遞承認:D – 2013-03-19 11:28:11