php无限极分类

无限分类,是指从一个最高分类开始,每个子分类都可以分出自己的若干个子分类,可以一直分下去,称为无限级分类;
如下是一个无限极分类数据表设计
php无限极分类插图
其中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;
    }

2 条评论

发表评论

*