2010-09-23 96 views
3

我有一個這樣的數組:PHP數組遞歸

Array ( 
[0] => Array ([id] => 1000 [enroller_id] => 1005) 

[1] => Array ([id] => 1005 [enroller_id] =>) 

[2] => Array ([id] => 1101 [enroller_id] => 1000) 

[3] => Array ([id] => 1111 [enroller_id] => 1000) 
) 

我想創建層次數組是這樣的:

Array(
[1005] => Array(
       [1000] => Array(
           [1101] => ... 
           [1111] => ... 
          ) 
       ) 
) 

你能幫助我嗎?我認爲這是一個遞歸。

回答

3

這將做你想做的,只是它不把第一個元素(1005)數組中:

function create_array($number, $data) 
{ 
    $result = array(); 
    foreach ($data as $row) 
    { 
     if ($row['enroller_id'] == $number) 
     { 
      $result[$row['id']] = create_array($row['id'], $data); 
     } 
    } 
    return $result; 
} 

print_r(create_array(1005, $data)); 

輸出:

Array 
(
    [1000] => Array 
     (
      [1101] => Array() 
      [1111] => Array() 
     ) 
) 
+1

謝謝。這是理想的解決方案! – pltvs 2010-09-23 09:23:49

+0

我們如何神奇地知道1005?它不應該在結果? – Wrikken 2010-09-23 09:37:45

+0

1005應該替換爲null,然後它將工作。通常情況下,遞歸很簡單,但會導致過多的迭代。 – Matthew 2010-09-23 09:43:21

3
//$paths is an array of references, in which _every_ item will sit at 'root' 
//level, but also as a reference as a child to it's parent. 

//initialize location of parentless/root items: 
$paths = array('N'=>array()); 

foreach($items as $item){ 
    //$target is the parent-id, or 'N' if we are a root node 
    $target = isset($item['enroller_id']) && !empty($item['enroller_id']) ? $item['enroller_id'] :'N'; 

    //if the parent is not yet in the paths array, make an entry for it 
    if(!isset($paths[$target]))  $paths[$target] = array(); 

    //if this item is not yet in the array (the previous statement could 
    //already have inserted it, make an array(
    if(!isset($paths[$item['id']])) $paths[$item['id']] = array(); 

    //add the current item as a reference to it's parent 
    $paths[$target][$item['id']] = &$paths[$item['id']]; 

    //Setting it as a reference has this consequence: 
    // when adding an item to the $paths[$id] array, it will 
    // automatically be added to $paths[$parent][$id], as 
    // both $paths[$id] & $paths[$parent][$id] point to the same 
    // location in memory. 
    // This goes to infinite depth: if $foo is a child of $id, and you 
    // add a node to it, it will be in 
    // $paths[$foo]    = array($child); 
    // $paths[$id][[$foo]   = array($child); 
    // $paths[$parent][$id][$foo] = array($child); 
    // 
    // Altering an item at any location in paths/the tree will alter it anywhere 
    // in the paths/tree, unsetting it anywhere only unset the data at that location, 
    // other locations will still have the same data (and the data will keep 
    // existing until the last reference is unset()) 

} 
//we are only interested in the 'root' nodes (all other nodes should be subnodes 
//in this tree 
$tree = $paths['N']; 
//remove all unused references in the $paths array 
//do remember to do this: cleaning up references is important 
unset($paths); 
//tree is now an array of 'normal' values (i.e. only 1 reference to each datapoint exists 
var_dump($tree); 

不要忘記unset路徑:引用真的可以咬你很難追查錯誤,如果你不採取適當的照顧。

+2

你能解釋一下這是如何工作? – Sjoerd 2010-09-23 09:22:26

+0

它只是在每次迭代時鏈接當前節點及其父節點。一開始,你只有兩個孤兒節點。最終他們會聯繫在一起,直到你擁有最終的樹。唯一的副作用是無根節點將被默默忽略,但這不是算法的錯誤。 – Matthew 2010-09-23 09:31:58

+0

這不是很好的解決方案。 – pltvs 2010-09-23 09:34:13