2012-10-07 271 views
10

我在PHP中的數組嵌套列表,它看起來像這樣:從創建多維數組

array (
    [0] => array (
     [id] => 1 
     [title] => "Title 1" 
     [parent_id] => NULL 
     [depth] => 0 
    ) 
    [1] => array (
     [id] => 2 
     [title] => "Title 2" 
     [parent_id] => NULL 
     [depth] => 0 
    ) 
    [2] => array (
     [id] => 3 
     [title] => "Title 3" 
     [parent_id] => 2 
     [depth] => 1 
    ) 
    [3] => array (
     [id] => 4 
     [title] => "Title 4" 
     [parent_id] => 2 
     [depth] => 1 
    ) 
    [4] => array (
     [id] => 5 
     [title] => "Title 5" 
     [parent_id] => NULL 
     [depth] => 0 
    ) 
    [5] => array (
     [id] => 6 
     [title] => "Title 6" 
     [parent_id] => 4 
     [depth] => 2 
    ) 
) 

我想要做的就是遍歷這個數組,並從它創建一個嵌套<ol>列表。所以結果應該是這樣的:

<ol> 
    <li>Title 1</li> // id = 1 
    <li>Title 2</li> // id = 2 
    <ol> 
     <li>Title 3</li> // id = 3 -> parent_id = 2 
     <li>Title 4</li> // id = 4 -> parent_id = 2 
     <ol> 
      <li>Title 6</li> // id = 6 -> parent_id = 4 
     </ol> 
    </ol> 
    <li>Title 5</li> // id = 5 
</ol> 

我一直在想辦法如何完成這件事。但到目前爲止,每一次嘗試失敗...

任何人任何想法如何,我可以創建這樣從這樣一個數組嵌套<ol>列表?

請注意,我沒有給定數據的控制。我只是做出一個API的調用,並返回JSON數據,我轉換成數組。和數組看起來就像我所描述的。

+0

表面看起來很簡單,但我認爲你仍然缺乏信息以便爲你的情況得到最好的答案。首先,你是如何獲得陣列的?它來自數據庫嗎?是否有可能以不同的方式儲存它,或者你以這種方式卡住?保證不會(現在或將來)的深度超過1或2,或者你會計劃做不確定數量的子級別嗎?這些類別多久添加一次或刪除?我建議你檢查一下http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/,因爲嵌套模型可能更符合你的需求。 – Mike

回答

13

您應該使用遞歸

首先在數組中的PHP'語法:

<?php 
$a=array (
    '0' => array (
     'id' => 1, 
     'title' => "Title 1", 
     'parent_id' => 'NULL', 
     'depth' => 0 
    ), 
    '1' => array (
     'id' => 2, 
     'title' => "Title 2", 
     'parent_id' => 'NULL', 
     'depth' => 0 
    ), 
    '2' => array (
     'id' => 3, 
     'title' => "Title 3", 
     'parent_id' => 2, 
     'depth' => 1 
    ), 
    '3' => array (
     'id' => 4, 
     'title' => "Title 4", 
     'parent_id' => 2, 
     'depth' => 1 
    ), 
    '4' => array (
     'id' => 5, 
     'title' => "Title 5", 
     'parent_id' => 'NULL', 
     'depth' => 0 
    ), 
    '5' => array (
     'id' => 6, 
     'title' => "Title 6", 
     'parent_id' => 4, 
     'depth' => 0 
    ) 
); 

這裏代碼

$level = 'NULL'; 

function r($a, $level) { 
    $r = "<ol>"; 
    foreach ($a as $i) { 
     if ($i['parent_id'] == $level) { 
      $r = $r . "<li>" . $i['title'] . r($a, $i['id']) . "</li>"; 
     } 
    } 
    $r = $r . "</ol>"; 
    return $r; 
} 

print r($a, $level); 

?> 

結果

<ol><li>Title 1<ol></ol></li><li>Title 2<ol><li>Title 3<ol> 
</ol></li><li>Title 4<ol><li>Title 6<ol></ol></li></ol></li></ol></li><li>Title 5 
<ol></ol></li></ol> 
  1. 標題1 \ n
    1. 標題2 \ n
      1. 標題3 \ n
        1. 標題4 \ n
          1. 名稱6 \ n
        2. 標題5 \ n

          EDITED支票溶液後

          爲了避免空葉子:

          function r($a, $level) { 
              $r = '' ; 
              foreach ($a as $i) { 
               if ($i['parent_id'] == $level) { 
                $r = $r . "<li>" . $i['title'] . r($a, $i['id']) . "</li>"; 
               } 
              } 
              return ($r==''?'':"<ol>". $r . "</ol>"); 
          } 
          
          4

          你可以嘗試以下

          $array = array (
              "0" => array (
               "id" => 1, 
               "title" => "Title 1", 
               "parent_id" => NULL, 
               "depth" => 0 
              ), 
              "1" => array (
               "id" => 2, 
               "title" => "Title 2", 
               "parent_id" => NULL, 
               "depth" => 0 
              ), 
              "2" => array (
               "id" => 3, 
               "title" => "Title 3", 
               "parent_id" => 2, 
               "depth" => 1 
              ), 
              "3" => array (
               "id" => 4, 
               "title" => "Title 4", 
               "parent_id" => 2, 
               "depth" => 1 
              ), 
              "4" => array (
               "id" => 5, 
               "title" => "Title 5", 
               "parent_id" => NULL, 
               "depth" => 0 
              ), 
              "5" => array (
               "id" => 6, 
               "title" => "Title 6", 
               "parent_id" => 4, 
               "depth" => 0 
              ) 
          ); 
          
          echo(make($array)); 
          

          輸出

          <ol> 
              <li>Title 1</li> 
              <li>Title 2</li> 
              <ol> 
               <li>Title 3</li> 
               <li>Title 4</li> 
               <ol> 
                <li>Title 6</li> 
               </ol> 
              </ol> 
              <li>Title 5</li> 
          </ol> 
          

          功能用於

          function make(array $array, $no = 0) { 
              $child = hasChildren($array, $no); 
              if (empty($child)) 
               return ""; 
              $content = "<ol>\n"; 
              foreach ($child as $value) { 
               $content .= sprintf("\t<li>%s</li>\n", $value['title']); 
               $content .= make($array, $value['id']); 
              } 
              $content .= "</ol>\n"; 
              return $content; 
          } 
          
          function hasChildren($array, $id) { 
              return array_filter($array, function ($var) use($id) { 
               return $var['parent_id'] == $id; 
              }); 
          } 
          

          See Live Demo

          +1

          很好的答案謝謝。你能告訴我如何設置最大深度,假設數組元素沒有「深度」鍵(因爲我沒有)。我想我們需要'$ level = 0;'和'$ max_level = 3'。但是如何將它們放置在你的函數中? – 2012-10-08 17:25:06

          +0

          @Baba,他是個不錯的地方。希望你必須有時間回顧一下。 – 2012-10-08 17:28:47

          1

          以下數組:

          Array 
          (
              [0] => Content 
              [1] => Array 
               (
                [0] => International 
                [1] => Array 
                 (
                  [0] => Mexico 
                  [1] => Array 
                   (
                    [0] => Tamaulipas 
                   ) 
          
                  [2] => USA 
                 ) 
          
               ) 
          
          ) 
          

          使用此功能:

          function r($element) { 
              foreach ($element as $value) { 
               if (!is_array($value)) { 
                echo "<li>"; 
                echo $value; 
               } else { 
                echo "<ul>"; 
                r($value); 
                echo "</li>"; 
                echo "</ul>"; 
               } 
              } 
          } 
          

          PHP代碼:

          echo "<ul>"; 
          r($array); 
          echo "</ul>"; 
          

          退貨:

          <ul> 
              <li>Public</li> 
              <li>User</li> 
              <li>Content 
               <ul> 
                <li>International 
                 <ul> 
                  <li>Mexico 
                   <ul> 
                    <li>Tamaulipas</li> 
                   </ul> 
                  </li> 
                  <li>USA</li> 
                 </ul> 
                </li> 
               </ul> 
              </li> 
          </ul>