2012-12-14 99 views
15

我使用PHP和mySQL與Idiorm。這可能不相關。PHP分層數組 - 父母和子女

我的PHP陣列

  • 這是父母與孩子的之間的關係。
  • 0是根父級。
  • 實施例:根母體0有子33具有子27具有 子71

該陣列結構可以根據需要用於解決該問題而改變。

array (
    33 => 
    array (
     0 => '27', 
     1 => '41', 
), 
    27 => 
    array (
     0 => '64', 
     1 => '71', 
), 
    0 => 
    array (
     0 => '28', 
     1 => '29', 
     2 => '33', 
), 
) 

我的分級結果

這樣的事情,但作爲一個數組...

0 => 
     28 
     29 
     33 
     27 => 
       64 
       71 
     41 

信息

  • 深度是未知的,它可無限。我試過foreach,但它可能不是這樣。

我自己的想法

  • 一些遞歸函數?
  • 一些while循環?

我嘗試了上述兩個,只是弄得一團糟。這是一個聰明人。

+2

查看http://stackoverflow.com/a/8587437/476在正確的方向微調... – deceze

回答

36

@deceze的建議工作。然而輸入數組需要改變豆蔻,像這樣...

$rows = array(
    array(
     'id' => 33, 
     'parent_id' => 0, 
    ), 
    array(
     'id' => 34, 
     'parent_id' => 0, 
    ), 
    array(
     'id' => 27, 
     'parent_id' => 33, 
    ), 
    array(
     'id' => 17, 
     'parent_id' => 27, 
    ), 
); 

https://stackoverflow.com/a/8587437/476

function buildTree(array $elements, $parentId = 0) { 
    $branch = array(); 

    foreach ($elements as $element) { 
     if ($element['parent_id'] == $parentId) { 
      $children = buildTree($elements, $element['id']); 
      if ($children) { 
       $element['children'] = $children; 
      } 
      $branch[] = $element; 
     } 
    } 

    return $branch; 
} 

$tree = buildTree($rows); 

print_r($tree); 
+0

工作對我很好。謝謝。 –

+0

很好的答案!謝謝。 – HartleySan

+0

只是在我的答案中增加了一點改進,希望沒關係! – Danish

4

我加入@JensTörnell的回答,使定義PARENT_ID的列名的選項,子數組鍵名,還有id的列名。

/** 
* function buildTree 
* @param array $elements 
* @param array $options['parent_id_column_name', 'children_key_name', 'id_column_name'] 
* @param int $parentId 
* @return array 
*/ 
function buildTree(array $elements, $options = [ 
    'parent_id_column_name' => 'parent_id', 
    'children_key_name' => 'children', 
    'id_column_name' => 'id'], $parentId = 0) 
    { 
    $branch = array(); 
    foreach ($elements as $element) { 
     if ($element[$options['parent_id_column_name']] == $parentId) { 
      $children = buildTree($elements, $options, $element[$options['id_column_name']]); 
      if ($children) { 
       $element[$options['children_key_name']] = $children; 
      } 
      $branch[] = $element; 
     } 
    } 
    return $branch; 
} 

由於功能相當普遍,我設法使用我的大多數項目的上述功能。

1

來自@JensTörnell的很好的回答,只是想增加一點改進,如果你的parent_id和id實際上是字符串而不是數字,那麼上面的方法將會失敗,並且在創建children數組之後,它會再次創建那些childrens數組個別陣列。爲了解決這個問題,你應該進行三重平衡檢查,並通過比較變量的數據類型(字符串)來進行比較。

對於基於字符串的標識和PARENT_ID在陣列

function buildTree(array $elements, $parentId = 0) { 
    $branch = array(); 

    foreach ($elements as $element) { 
     if ((string)$element['parent_id'] === (string)$parentId) { 
      $children = buildTree($elements, $element['id']); 
      if ($children) { 
       $element['children'] = $children; 
      } 
      $branch[] = $element; 
     } 
    } 

    return $branch; 
} 

另外,如果有人渴望,他可以添加第三個參數的功能,以及指定變量數據類型動態即function buildTree(array $elements, $parentId = 0, $datatype='string')但那麼你將有采取任何其他錯誤發生。

希望它能幫助別人!