2012-10-14 52 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()函数。 –

相关问题