php無限極分類(遞歸+引用)、生成(樹形/層級)結構、拼接結構(option選項)、數組遞歸/遞歸查詢


//////////////////////***樹形結構***/////////////////////////////

/**
 * 遞歸生成樹形結構
 * @param array $array 所有分類數據
 * @param int $pid 父級id
 * @return array
 */
function getTrees($array,$pid = 0){
	$tree = array();
	foreach ($array as $key => $value) {
		if ($value['pid'] == $pid) {
			unset($array[$key]);/* 銷燬節點,減少後續遞歸消耗 */
			$child = getTrees($array, $value['id']);
			if (!empty($child)){
				$value['child'] = $child;
			}
			$tree[] = $value;
		}
	}
	return $tree;
}




//////////////////////***層級結構***/////////////////////////////


/**
 * 遞歸生成層級結構
 * @param array $array 所有分類數據
 * @param int $pid 父級id
 * @param int $level 層級
 * @return mixed
 */
function getChilds($array,$pid = 0,$level = 0){
	static  $res;//聲明靜態數組,用於保存數據
	foreach ($array as $key => $value){
		//第一次找到根節點 也就是pid=0的節點
		if($value['pid'] == $pid){
			$value['level'] = $level;
			$res[] = $value;
			unset($array[$key]);/* 銷燬節點,減少後續遞歸消耗 */
			//遞歸查找父ID爲該節點id的節點,層級則爲原級別+1
			getChilds($array,$value['id'],$level+1);
		}
	}
	return $res;
}



/**
 * (遞歸和引用)生成層級結構
 * @param array $array 所有分類數據
 * @param int $pid 父級id
 * @param int $level 層級
 * @param array $res 保存數據
 * @return array
 */
function getChildsCite($array,$pid = 0,$level = 0,&$res = array()){
	foreach ($array as $key => $value) {
		if ($value['pid'] == $pid) {
			$value['level'] = $level;
			$res[] = $value;
			unset($array[$key]);/* 銷燬節點,減少後續遞歸消耗 */
			getChildsCite($array, $value['id'],$level+1,$res);
		}
	}
	return $res;
}
/* 和靜態變量使用方式一樣,感覺靜態變量方式比較好 */





//////////////////////***拼接結構***/////////////////////////////

/**
 * 遞歸形式生成拼接結構
 * @param array $array 所有分類數據
 * @param int $pid 父級id
 * @param int $selval 選中的id (編輯時一般爲父級id)
 * @param int $current 當前編輯的id(用於編輯分類時不顯示自己的id)
 * @param int $level 層級
 * @return string
 */
function getTreesSplice($array,$pid = 0,$selval = 0,$current = 0,$level = 0){
	$str = '';
	foreach ($array as $key => $value) {
		if ($value['pid'] == $pid) {
			unset($array[$key]);/* 銷燬節點,減少後續遞歸消耗 */
			$levelstr = str_repeat('  ',$level);
			$selected = ($selval ==  $value['id']) ? 'selected' : '';
			if ($current !=  $value['id']){
				$str .= '<option '.$selected.' value="'.$value['id'].'">'.$levelstr.$value['name'].'</option>';
			}
			$str .= getTreesSplice($array, $value['id'],$selval,$current,$level+1);
		}
	}
	return $str;
}


/**
 * 遞歸形式(頭部插入父級選項)生成拼接結構
 * @param array $array 所有分類數據
 * @param int $pid 父級id
 * @param int $selval 選中的id (編輯時一般爲父級id)
 * @param int $current 當前編輯的id(用於編輯分類時不顯示自己的id)
 * @param int $level 層級
 * @param bool $topstr 是否插入父級選項
 * @return string
 */
function getTreesSpliceTopStr($array,$pid = 0,$selval = 0,$current = 0,$level = 0,$topstr = false){
	$str = '';
	foreach ($array as $key => $value) {
		if ($topstr && $value['id'] == $pid){
			$str = substr_replace($str,'<option value="'.$value['id'].'" >'.$value['name'].'</option>',0,0);
		}
		if ($value['pid'] == $pid) {
			unset($array[$key]);/* 銷燬節點,減少後續遞歸消耗 */
			$levelstr = str_repeat('&emsp;&emsp;',$level);
			$selected = ($selval ==  $value['id']) ? 'selected' : '';
			if ($current !=  $value['id']){
				$str .= '<option '.$selected.' value="'.$value['id'].'">'.$levelstr.$value['name'].'</option>';
			}
			$str .= getTreesSplice($array, $value['id'],$selval,$current,$level+1);
		}
	}
	return $str;
}


/**
 * (遞歸+靜態變量形式)生成拼接結構
 * @param array $array 所有分類數據
 * @param int $pid 父級id
 * @param int $selval 選中的id (編輯時一般爲父級id)
 * @param int $current 當前編輯的id(用於編輯分類時不顯示自己的id)
 * @param int $level 層級
 * @return string
 */
function getChildsSplice($array,$pid = 0,$selval = 0,$current = 0,$level = 0){
	static  $str;//聲明靜態變量,用於保存數據
	foreach ($array as $key => $value){
		//第一次找到根節點 也就是pid=0的節點
		if($value['pid'] == $pid){
			$levelstr = str_repeat('&emsp;&emsp;',$level);
			$selected = ($selval ==  $value['id']) ? 'selected' : '';
			if ($current !=  $value['id']){
				$str .= '<option '.$selected.' value="'.$value['id'].'">'.$levelstr.$value['name'].'</option>';
			}
			unset($array[$key]);/* 銷燬節點,減少後續遞歸消耗 */
			//遞歸查找父ID爲該節點id的節點,層級則爲原級別+1
			getChildsSplice($array,$value['id'],$selval,$current,$level+1);
		}
	}
	return $str;
}


/**
 * 遞歸查表形式生成拼接結構
 * @param int $pid 父級id
 * @param int $selval 選中的id (編輯時一般爲父級id)
 * @param int $current 當前編輯的id(用於編輯分類時不顯示自己的id)
 * @param int $level 層級
 * @return string
 */
function GetCategoriesSplice($pid = 0,$selval = 0,$current = 0,$level = 0){
	/* 查詢父級下的數據 */
	$array=\think\Db::table('categories')->where('parent',$pid)->select();
	$str = '';
	foreach($array as $key => $value) {
		if($value['parent'] == $pid) {
			$levelstr = str_repeat('&emsp;&emsp;',$level);
			$selected = ($selval ==  $value['id']) ? 'selected' : '';
			if ($current !=  $value['id']){
				$str .= '<option '.$selected.' value="'.$value['id'].'">'.$levelstr.$value['name'].'</option>';
			}
			$str .= GetCategoriesSplice($value['id'],$selval,$current,$level+1);/* 遞歸查詢 */
		}
	}
	return $str;
}




////***調用***////

//需要遞歸的數組

$arr = array(
	array('id'=>1,'name'=>'名稱1','pid'=>0),
	array('id'=>2,'name'=>'名稱2','pid'=>0),
	array('id'=>3,'name'=>'名稱3','pid'=>0),
	array('id'=>4,'name'=>'名稱4','pid'=>0),
	array('id'=>5,'name'=>'名稱5','pid'=>0),
	array('id'=>6,'name'=>'名稱1-1','pid'=>1),
	array('id'=>7,'name'=>'名稱1-2','pid'=>1),
	array('id'=>8,'name'=>'名稱2-1','pid'=>2),
	array('id'=>9,'name'=>'名稱2-2','pid'=>2),
	array('id'=>10,'name'=>'名稱3-1','pid'=>3),
	array('id'=>11,'name'=>'名稱1-1-1','pid'=>6),
	array('id'=>12,'name'=>'名稱1-1-2','pid'=>6),
	array('id'=>13,'name'=>'名稱1-2-1','pid'=>7),
	array('id'=>14,'name'=>'名稱2-1-1','pid'=>8),
	array('id'=>15,'name'=>'名稱2-1-2','pid'=>8),
	array('id'=>16,'name'=>'名稱2-2-1','pid'=>9),
	array('id'=>17,'name'=>'名稱2-1-1-1','pid'=>14),
	array('id'=>18,'name'=>'名稱2-1-2-1','pid'=>15),
	array('id'=>19,'name'=>'名稱2-1-1-1-1','pid'=>17),
	array('id'=>20,'name'=>'名稱3-1-1','pid'=>10),
);

//$trees = getTrees($arr);
//print_r($trees);


//$childs = getChilds($arr);
//print_r($childs);

//$childscite = getChildsCite($arr);
//print_r($childscite);

//echo '<select>';
//$treessplicestr = getTreesSplice($arr,0,6,11);
//print_r($treessplicestr);
//echo '</select>';


//echo '<select>';
//$treessplicetopstr = getTreesSpliceTopStr($arr,2,0,0,1,true);
//print_r($treessplicetopstr);
//echo '</select>';



//echo '<select>';
//$getcategoriessplice = GetCategoriesSplice();
//print_r($getcategoriessplice);
//echo '</select>';die;


 

以下是參考文檔:一次循環(引用生成樹形)

參考鏈接-->

 



/**
 * 核心函數, 將列表數據轉化樹形結構
 * 使用前提必須是先有父後有子, 即兒子的id必須小於父親id
 * 列表數據必須安裝id從小到大排序
 * @param array $lists 原始列表數據
 * @param string $childKey 字段名
 * @return array 返回樹形數據
 */
function listToTree($lists, $childKey = 'children'){
	$map = [];
	$res = [];
	foreach($lists as $id => &$item){
		// 獲取出每一條數據的父id
		$pid = &$item['pid'];
		// 將每一個item的引用保存到$map中
		$map[$item['id']] = &$item;
		// 如果在map中沒有設置過他的pid, 說明是根節點, pid爲0,
		if(!isset($map[$pid])){
			// 將pid爲0的item的引用保存到$res中
			$res[$id] = &$item;
		}else{
			// 如果在map中沒有設置過他的pid, 則將該item加入到他父親的葉子節點中
			$pItem = &$map[$pid];
			$pItem[$childKey][] = &$item;
		}
	}
	return $res;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章