无限分类,是指从一个最高分类开始,每个子分类都可以分出自己的若干个子分类,可以一直分下去,称为无限级分类;
无限极分类数据表设计
cateid 为栏目id,parentid为其父栏目id。
数据
array:8 [▼
0 => array:4 [▼
"cateid" => "1"
"title" => "家电"
"parentid" => "0"
"createtime" => 0
]
1 => array:4 [▼
"cateid" => "2"
"title" => "服装"
"parentid" => "0"
"createtime" => 0
]
2 => array:4 [▼
"cateid" => "3"
"title" => "上衣"
"parentid" => "2"
"createtime" => 0
]
3 => array:4 [▼
"cateid" => "4"
"title" => "衬衣"
"parentid" => "3"
"createtime" => 0
]
4 => array:4 [▼
"cateid" => "5"
"title" => "裤子"
"parentid" => "2"
"createtime" => 0
]
5 => array:4 [▼
"cateid" => "6"
"title" => "短裤"
"parentid" => "5"
"createtime" => 0
]
6 => array:4 [▼
"cateid" => "7"
"title" => "冰箱"
"parentid" => "1"
"createtime" => 0
]
7 => array:4 [▼
"cateid" => "8"
"title" => "食品"
"parentid" => "0"
"createtime" => 0
]
]
createtime 为栏目创建时间,此处没有用到。
无限极分类方式1(利用深度添加前缀)
效果:
array:8 [▼
1 => "|---家电"
7 => "|---|---冰箱"
2 => "|---服装"
3 => "|---|---上衣"
4 => "|---|---|---衬衣"
5 => "|---|---裤子"
6 => "|---|---|---短裤"
8 => "|---食品"
]
递归算法
//获取排序后的分类,递归算法
public function getOptions($list,$parentid = 0,$level = 0){
$arrTree = [];
if(empty($list)){
return [];
}
$level++;
foreach($list as $key => $val){
if($val['parentid'] == $parentid){
$val['level'] = $level;
$arrTree[] = $val;
unset($list[$key]);
$arrTree = array_merge($arrTree,$this->getOptions($list, $val['cateid'], $level));//找其子类合并
}
}
return $arrTree;
}
经过上述方法后所得结果如下,可以看到已经将父栏目与子栏目放到了一起,并增加了level,只需要根据level的值,来添加相应的前缀数量即可
array:8 [▼
0 => array:5 [▼
"cateid" => "1"
"title" => "家电"
"parentid" => "0"
"createtime" => 0
"level" => 1
]
1 => array:5 [▼
"cateid" => "7"
"title" => "冰箱"
"parentid" => "1"
"createtime" => 0
"level" => 2
]
2 => array:5 [▼
"cateid" => "2"
"title" => "服装"
"parentid" => "0"
"createtime" => 0
"level" => 1
]
3 => array:5 [▼
"cateid" => "3"
"title" => "上衣"
"parentid" => "2"
"createtime" => 0
"level" => 2
]
4 => array:5 [▼
"cateid" => "4"
"title" => "衬衣"
"parentid" => "3"
"createtime" => 0
"level" => 3
]
5 => array:5 [▼
"cateid" => "5"
"title" => "裤子"
"parentid" => "2"
"createtime" => 0
"level" => 2
]
6 => array:5 [▼
"cateid" => "6"
"title" => "短裤"
"parentid" => "5"
"createtime" => 0
"level" => 3
]
7 => array:5 [▼
"cateid" => "8"
"title" => "食品"
"parentid" => "0"
"createtime" => 0
"level" => 1
]
]
//添加前缀 |--- 并且去除多余项
public function addPrefix($list,$prefix="|---"){
$arr = [];
foreach($list as $val){//将$prefix重复level次,拼接到原title处
$arr[$val['cateid']] = str_repeat($prefix,$val['level']).$val['title'];
}
return $arr;
}
非递归算法
//获取排序后的分类,非递归算法,借助栈的思想
public function getOptionsStack($list)
{
$list = array_reverse($list);
$arr = [];
$temp = [];
foreach($list as $key=>$val){//先取出所有的顶级分类
if($val['parentid']==0){
$val['level'] = 1;
unset($list[$key]);
array_push($temp,$val);
}
}
while(count($temp)>0){
$par = array_pop($temp);//array_pop,然后将其子分类入栈
$arr[] = $par;
foreach($list as $key=>$val){
if($val['parentid']==$par['cateid']){
$val['level'] = $par['level']+1;
unset($list[$key]);
array_push($temp,$val);
}
}
}
return $arr;
}
无限极分类方式2
实现效果如下
array:3 [▼
0 => array:5 [▼
"cateid" => "1"
"title" => "家电"
"parentid" => "0"
"createtime" => 0
"_child" => array:1 [▼
0 => array:4 [▼
"cateid" => "7"
"title" => "冰箱"
"parentid" => "1"
"createtime" => 0
]
]
]
1 => array:5 [▼
"cateid" => "2"
"title" => "服装"
"parentid" => "0"
"createtime" => 0
"_child" => array:2 [▼
0 => array:5 [▼
"cateid" => "3"
"title" => "上衣"
"parentid" => "2"
"createtime" => 0
"_child" => array:1 [▼
0 => array:4 [▼
"cateid" => "4"
"title" => "衬衣"
"parentid" => "3"
"createtime" => 0
]
]
]
1 => array:5 [▼
"cateid" => "5"
"title" => "裤子"
"parentid" => "2"
"createtime" => 0
"_child" => array:1 [▼
0 => array:4 [▼
"cateid" => "6"
"title" => "短裤"
"parentid" => "5"
"createtime" => 0
]
]
]
]
]
2 => array:4 [▼
"cateid" => "8"
"title" => "食品"
"parentid" => "0"
"createtime" => 0
]
]
递归算法
//无限极分类,递归算法2
public function getOptionsAno($list,$root=0)
{
$tree=array();
foreach($list as $key=> $val){
if($val['parentid']==$root){
//获取当前$pid所有子类
unset($list[$key]);
if(! empty($list)){
$child=$this->getOptionsAno($list,$val['cateid']);
if(!empty($child)){
$val['_child']=$child;
}
}
$tree[]=$val;
}
}
return $tree;
}
非递归算法
代码比较难看懂
//无限极分类,非递归算法2
public function getOptionsAnother($list,$root=0){
// 创建Tree
$tree = array();
if(is_array($list)) {
// 创建基于主键的数组引用
$refer = array();
foreach ($list as $key => $data) {
$refer[$data['cateid']] =& $list[$key];
}
foreach ($list as $key => $data) {
// 判断是否存在parent
$parentId = $data['parentid'];
if ($root == $parentId) {
$tree[] =& $list[$key];
}else{
if (isset($refer[$parentId])) {
$parent =& $refer[$parentId];
$parent['_child'][] =& $list[$key];
}
}
}
}
return $tree;
}