2012-10-14 51 views
0

我有一個2維PHP數組,我需要將其轉入樹中。每個內部數組中的'路徑'值是當前節點的枚舉路徑。 (我從Bill Karwin的關於SQL反模式的書中得到了這個想法)。如何將此PHP數組結構轉換爲多維樹?

所以,我開始與陣列看起來是這樣的:

array(
[1] => array('name' => 'Animals', 'path' => '1/'), 
[2] => array('name' => 'Birds', 'path' => '1/3/'), 
[3] => array('name' => 'Cockatoos', 'path' => '1/3/5/'), 
[4] => array('name' => 'Fish', 'path' => '1/2/'), 
[5] => array('name' => 'Kookaburras', 'path' => '1/3/4/') 
) 

正如你可能已經收集,外數組的索引是沒有意義的。我只是在'name'上按字母順序排列了內部數組,而PHP在外部數組上指定了數字索引。就「路徑」值而言,每個路徑的最後一個分區是該節點的僞ID,即動物是節點1,鳥是節點3.您可以看到完整路徑描述了路由到給定節點,例如'鸚鵡'由'鳥'培育,由'動物'培育。

我想保留節點的字母順序,但將它們按其父級進行分組。換句話說,我想,看起來是這樣的(在其自然順序)一個數組:

[1]   => 'Animals' 
[1][3]  => 'Birds' 
[1][3][5] => 'Cockatoos' 
[1][3][4] => 'Kookaburras' 
[1][2]  => 'Fish' 

我打算遍歷這個遞歸打印樹的可視化表示。

在嘗試從一種類型的數組轉換爲另一種類型時,我的方法使用了遞歸,變量變量和正則表達式,但我一直跑到路障中。

另外,是否有我應該考慮的SPL數據結構或迭代器?

非常感謝!

編輯:對不起,應該提到,樹的深度是可變的。上面的例子有三個層次,但實際上會有更多。

回答

2

這會工作,不管樹的由於使用eval()函數(代表評價)的深度,可能。但字母排序還沒有正常工作。由於父數組的索引保持不變,因此會混淆在一起。至少你可以建立一棵樹已經:)

<?php 
$a = array(
     array('name' => 'Animals', 'path' => '1/'), 
     array('name' => 'Birds', 'path' => '1/3/'), 
     array('name' => 'Eagles', 'path' => '1/3/3/'), 
     array('name' => 'Cockatoos', 'path' => '1/3/5/'), 
     array('name' => 'Fish', 'path' => '1/2/'), 
     array('name' => 'Kookaburras', 'path' => '1/3/4/') 
    ); 
Iterate($a); 
$tree = Iterate($a); 

var_dump($tree); 

OneLevelDeeper($tree); 
var_dump($tree); 

function Iterate($ChildArray) 
{ 
    $TreeArray; 
    foreach($ChildArray as $Key => $Value) 
    { 
     //echo $Key.': '.$Value['name']."\r\n"; 
     $exp = explode('/', $Value['path']); 
     $path; 
     foreach($exp as $int) 
     { 
      if($int != "") 
      { 
       $path[] = $int; 
      } 
     } 

     //Using Eval() function of PHP 
     $BuildSourceToEvaluate = '$TreeArray'; 
     for($i=0; $i<(count($path)-1); $i++) 
     { 
      $BuildSourceToEvaluate .= '[$path['.$i.']]'; 
     } 
     $BuildSourceToEvaluate .= '[] = $Value[\'name\'];'; 
     echo $BuildSourceToEvaluate."\r\n"; 
     Eval($BuildSourceToEvaluate); 
     //print_r($path); 
     /* 
     switch(count($path)) 
     { 
      case 0: 
      break; 
      case 1: 
       $TreeArray[] = $Value['name']; 
       //$TreeArray[$path[0]] = $Value['name']; //Use this for unique paths and keeping hold of the last ID in the tree path 
       //$TreeArray[$path[0]][] = $Value['name']; //Use this for non-unique tree paths 
      break; 
      case 2: 
       $TreeArray[$path[0]][] = $Value['name']; 
       //$TreeArray[$path[0]][$path[1]] = $Value['name']; //Use this for unique paths and keeping hold of the last ID in the tree path 
       //$TreeArray[$path[0]][$path[1]][] = $Value['name']; //Use this for non-unique tree paths 
      break; 
      case 3: 
       $TreeArray[$path[0]][$path[1]][] = $Value['name']; 
       //$TreeArray[$path[0]][$path[1]][$path[2]] = $Value['name']; //Use this for unique paths and keeping hold of the last ID in the tree path 
       //$TreeArray[$path[0]][$path[1]][$path[2]][] = $Value['name']; //Use this for non-unique tree paths 
      break; 
     } 
     */ 
     unset($path); 
    } 
    return $TreeArray; 
} 


function OneLevelDeeper(&$a) 
{ 
    sort($a); 
    foreach($a as $Key => $Value) 
    { 
     if(is_array($Value)) 
     { 
      sort($a[$Key]); 
      OneLevelDeeper($a[$Key]); 
     } 
    } 
} 

?> 
+0

邁克,謝謝你給這個裂縫。儘管如此,請參閱我原始問題中的編輯。樹的深度是可變的。對不起,我應該在一開始就說清楚。將有興趣看看你現在如何解決問題... –

+0

@Kim - 這仍然沒有問題。樹的最大深度可能有多大?您可以使用相同的方式將新案例添加到案例中,以向樹添加額外深度。否則,你將不得不使用PHP的Eval()函數。 –

相關問題