標籤:
需求描述:
現有一個節點集合
可以視為一個二維數組
1 array(5) { 2 [0] => array(4) { 3 ["id"] => string(1) "1" 4 ["name"] => string(5) "Admin" 5 ["title"] => string(12) "後台應用" 6 ["pid"] => string(1) "0" 7 } 8 [1] => array(4) { 9 ["id"] => string(1) "2"10 ["name"] => string(5) "Index"11 ["title"] => string(12) "前端應用"12 ["pid"] => string(1) "0"13 }14 [2] => array(4) {15 ["id"] => string(1) "3"16 ["name"] => string(5) "Index"17 ["title"] => string(12) "後台首頁"18 ["pid"] => string(1) "1"19 }20 [3] => array(4) {21 ["id"] => string(1) "4"22 ["name"] => string(10) "MsgManager"23 ["title"] => string(12) "文章管理"24 ["pid"] => string(1) "1"25 }26 [4] => array(4) {27 ["id"] => string(1) "5"28 ["name"] => string(4) "Rbac"29 ["title"] => string(10) "RBAC許可權"30 ["pid"] => string(1) "1"31 }32 }數組arr01
pid、level欄位解釋:
pid表示父級的id。取值範圍{0,1,2,3,... ,n,...}
pid的值為0,表示這條記錄不屬於任何其他記錄。
pid的值為1,表示這條記錄屬於id為1的記錄。即為id為1的記錄的子記錄。
pid的值為2,表示這條記錄屬於id為2的記錄。即為id為2的記錄的子記錄。
......
以此類推。
level展示層次、層級。取值範圍{1,2,3},即為3個層次、或者是3個層級
level的值為1,表示第一層次,最高層次級,最進階別。
level的值為2,表示第二層次。
level的值為3,表示第三層次。
例如,如果level=1代表導覽列中的首頁、公司部門、產品介紹等等
那麼,level=2就代表部門A、部門B、...;產品A、產品B、產品C、...
這樣,僅僅靠一個二維表,就能儲存下各條記錄的歸屬關係。
但是,為了使用foreach嵌套的方式迴圈輸出有層次的資料,我們需要把原始的二維數組,按照歸屬關係組合到一起。
形如:一個多維陣列
1 array(2) { 2 [0] => array(5) { 3 ["id"] => string(1) "1" 4 ["name"] => string(5) "Admin" 5 ["title"] => string(12) "後台應用" 6 ["pid"] => string(1) "0" 7 ["child"] => array(3) { 8 [0] => array(5) { 9 ["id"] => string(1) "3"10 ["name"] => string(5) "Index"11 ["title"] => string(12) "後台首頁"12 ["pid"] => string(1) "1"13 ["child"] => array(0) {14 }15 }16 [1] => array(5) {17 ["id"] => string(1) "4"18 ["name"] => string(10) "MsgManager"19 ["title"] => string(12) "文章管理"20 ["pid"] => string(1) "1"21 ["child"] => array(0) {22 }23 }24 [2] => array(5) {25 ["id"] => string(1) "5"26 ["name"] => string(4) "Rbac"27 ["title"] => string(10) "RBAC許可權"28 ["pid"] => string(1) "1"29 ["child"] => array(0) {30 }31 }32 }33 }34 [1] => array(5) {35 ["id"] => string(1) "2"36 ["name"] => string(5) "Index"37 ["title"] => string(12) "前端應用"38 ["pid"] => string(1) "0"39 ["child"] => array(0) {40 }41 }42 }數組arr02
我們寫一個遞迴函式node_merge()來實現:
1 <?php 2 /** 3 * 遞迴重組節點資訊多維陣列 4 * @param [array] $node [要處理的節點數組:二維數組] 5 * @param [int] $pid [父級ID] 6 * @return [array] [樹狀結構的節點體系:多維陣列] 7 */ 8 function node_merge($node,$pid=0){ 9 $arr=array();10 11 12 foreach ($node as $v) {13 if ($v[‘pid‘]==$pid) {14 $v[‘child‘]=node_merge($node,$v[‘id‘]);15 $arr[]=$v;16 }17 }18 19 return $arr;20 }21 ?>
怎麼理解這個函數呢?
我們以處理原始的二維數組(arr01)的資料為例,通過調用node_merge()函數,轉換成可直接看出歸屬關係的多維陣列(arr02)。
函數中的$node即為arr01,當傳入arr01數組時,$pid初始化為0值,函數建立一個臨時數組(arr);
接著,用foreach迴圈,讀取第一條記錄(id=1那條記錄),判斷式處理:如果第一條記錄中的父級id是0,那麼正好等於初始化的$pid,
那麼,在第一條記錄中,加上一個欄位(child)。第一條記錄中的child欄位的取值,來自pid=1的記錄(想想為什麼。提示:從node_merge($node,$v[‘id‘]);中的$v[‘id‘]入手)。
而取值操作是來自$arr[]=$v;這句命令。
這使用的是遞迴,函數調用函數,這是我的理解,如果你有更好的理解,可以給我留言。郵箱:[email protected]
ThinkPHP中:使用遞迴寫node_merge()函數