2010-05-23 269 views
6

当检索从MySQL的层级结构(具有一个ID列和一个PARENT列标志着分层关系表),我的结果映射到如下枚举阵列(在这个例子中的数字是任意的):PHP数组 - 如何将一维数组转换为嵌套多维数组?

Array ([3] => Array ([7] => Array()), [7] => Array ([8] => Array())) 

通知3是7的父亲,而7是8的父亲(这可以继续;并且任何父母可以有多个孩子)。

我想这个阵列收缩成嵌套多维数组如下:

Array ([3] => Array ([7] => Array ([8] => Array()))) 

即,每个新的ID被自动地分配一个空数组。无论如何,任何ID的孩子都会被推入父母的阵列。

看看下面的图作进一步澄清:

alt text http://img263.imageshack.us/img263/4986/array.gif

这可能会导致一个复杂的递归操作,因为我总是要检查是否父与任何特定的ID已经存在(如果是这样,请将值推入其数组中)。

是否有一个内置的PHP函数可以帮助我呢?你有什么想法如何去构建这个?为了什么值得我用这个在wordpress中建立一个导航栏(它可以包含类别,子类别,帖子...基本上任何东西)。

+2

+1为漂亮的图形:) – Alec 2010-05-23 17:26:27

回答

1

这个想法是,你保留一个辅助数组与你找到的所有节点(父母和孩子)。这个数组的值是引用你的结果的引用。

此构建树以线性时间(array_key_exists确实一个哈希表查找,这是对平均O(1)):

//table contains (id, parent) 
$orig = array(
    11 => 8, 
    7 => 3, 
    8 => 7, 
    99 => 8, 
    16 => 8, 
); 

$childrenTable = array(); 
$result = array(); 

foreach ($orig as $n => $p) { 
    //parent was not seen before, put on root 
    if (!array_key_exists($p, $childrenTable)) { 
     $childrenTable[$p] = array(); 
     $result[$p] = &$childrenTable[$p]; 
    } 
    //child was not seen before 
    if (!array_key_exists($n, $childrenTable)) { 
     $childrenTable[$n] = array(); 
    } 

    //root node has a parent after all, relocate 
    if (array_key_exists($n, $result)) { 
     unset($result[$n]); 
    } 

    $childrenTable[$p][$n] = &$childrenTable[$n]; 
} 
unset($childrenTable); 

var_dump($result); 

给出

array(1) { 
    [3]=> 
    array(1) { 
    [7]=> 
    array(1) { 
     [8]=> 
     array(3) { 
     [11]=> 
     array(0) { 
     } 
     [99]=> 
     array(0) { 
     } 
     [16]=> 
     array(0) { 
     } 
     } 
    } 
    } 
} 

编辑:在未固化$childrenTable结束清除参考标志。在实践中,无论如何你可能会想要在一个函数内部进行操作。

+0

感谢您的努力,我现在正在讨论它,看看它是否确实是防弹的。 – Gal 2010-05-23 18:11:32

1

这个问题及其答案应该对你有所帮助:turn database result into array

请务必阅读@Bill Karwin的PDF演示文稿,特别是关于Closure表格的主题。

相关问题