2010-05-23 268 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表格的主題。

相關問題