分类

分类

<?php
/**
 * 分类.
 * [引用](https://blog.csdn.net/u012600104/article/details/80543883)
 * Date: 2019-04-06
 * Time: 20:45
 */

class Cate
{
    public function index()
    {
        $data = $this->getData();
        // 分类查找出的数据
//        $tree = $this->getTree($data);
//        $tree = $this->getTree2($data);
        $tree = $this->diedai($data);
        // 对分类级别添加前缀
        $list = $this->setPrefix($tree, '---|');

        var_dump($list);
    }

    /**
     * 设置层级前缀
     * @param $data array
     * @param $prefix string
     * @return array
     */
    protected function setPrefix($data, $prefix)
    {
        $list = [];
        // 前缀个数
        $num = 1;
        // 类的层级[层级=>前缀个数]
        $box = [0 => 1];
        // 封装数组中当前元素的值
        while ($val = current($data)) {
            $key = key($data);
            // 当类的层级更改时,前缀个数增加
            if (array_key_exists($val['parentid'], $box)) {
                $num = $box[$val['parentid']];
            } else {
                if ($data[$key - 1]['parentid'] !== $val['parentid']) {
                    $num++;
                }
            }
            // 添加前缀
            $val['title'] = str_repeat($prefix, $num) . $val['title'];
            $list[] = $val;
            next($data);
        }
        return $list;
    }

    /**
     * 商品分类
     * @param $cates
     * @param int $pid
     * @return array
     */
    protected function getTree($cates, $pid = 0, $num = 1)
    {
//        $tree = [];
//        foreach ($cates as $k => $cate) {
//            if ($cate['parentid'] == $pid) {
//                // 父类数组赋值给 $tree
//                $tree[] = $cate;
//                // 把该节点从数组中移除,减少递归损耗
//                unset($cates[$k]);
//                // 找出子类合并到父类
//                $tree = array_merge($tree, $this->getTree($cates, $cate['cateid']));
//            }
//        }

        // 声明静态数组,避免递归调用时多次声明导致数组覆盖
        static $tree = [];
        foreach ($cates as $k => $cate) {
            if ($cate['parentid'] == $pid) {
                // 添加前缀
                $cate['title'] = str_repeat('---|', $num);
                // 父类数组赋值给 $tree
                $tree[] = $cate;
                // 把该节点从数组中移除,减少递归损耗
                unset($cates[$k]);
                // 递归
                $this->getTree($cates, $cate['cateid'], $num + 1);
            }
        }

        return $tree;
    }

    /**
     * 递归加引用实现无限极分类
     * @param $items
     * @return array
     */
    public function getTree2($array)
    {
        //第一步 构造数据
        $items = array();
        foreach ($array as $value) {
            $items[$value['cateid']] = $value;
        }
        //第二部 遍历数据 生成树状结构
        $tree = array();
        foreach ($items as $key => $item) {
            if (isset($items[$item['parentid']])) {
                $items[$item['parentid']]['son'][] = &$items[$key];
            } else {
                $tree[] = &$items[$key];
            }
        }
        return $tree;
    }

    protected function diedai($data, $id = 0)
    {
        $task = array($id);//任务表此时放进的$id是为了找儿子,然后再儿子中找孙子,
        $tree = array();//地区表
        while (!empty($task)) {
            $flag = false;
            foreach ($data as $k => $v) {
                if ($v['parentid'] == $id) {
                    $tree[] = $v;//把找到的项放进$tree数组
                    array_push($task, $v['cateid']);//每次把找到的儿子的id加进来
                    $id = $v['cateid'];//每次把$id设成刚加进来的一项的id
                    unset($data[$k]);//把找到的项删除,此处类似排除法
                    $flag = true;//执行这一步说明上面的$id找到儿子了,如果为false说明这一if语句根本没执行同时说明最后
                    //的$id没儿子,然后执行下面的if语句,把$id设为倒数第二项
                }
            }
            if ($flag == false) {//当执行这一步时 说明上一步的foreach没执行也就是说明$task最后一项没找到孩子
                array_pop($task);//删除最后一项
                $id = end($task);//把$id设为倒数第二项,放到上面的foreach里去执行,找倒数第二项的儿子
            }
        }
        return $tree;
    }

    /**
     * 商品数据
     * @return array
     */
    protected function getData()
    {
        $data = array(
            0 =>
                array('cateid' => '1', 'title' => 'a', 'parentid' => '0', 'createtime' => '1527845919'),
            1 =>
                array('cateid' => '2', 'title' => 'b', 'parentid' => '0', 'createtime' => '1527845936'),
            2 =>
                array('cateid' => '3', 'title' => 'aa_0', 'parentid' => '1', 'createtime' => '1527845951'),
            3 =>
                array('cateid' => '4', 'title' => 'bb_0', 'parentid' => '2', 'createtime' => '1527845968'),
            4 =>
                array('cateid' => '5', 'title' => 'bb_1', 'parentid' => '2', 'createtime' => '1527846023'),
            5 =>
                array('cateid' => '6', 'title' => 'aa_1', 'parentid' => '1', 'createtime' => '1527846031'),
            6 =>
                array('cateid' => '7', 'title' => 'aa_2', 'parentid' => '1', 'createtime' => '1527850236'),
            7 =>
                array('cateid' => '8', 'title' => 'bb_2', 'parentid' => '2', 'createtime' => '1527850251'),
            8 =>
                array('cateid' => '9', 'title' => 'c', 'parentid' => '0', 'createtime' => '1527859601'),
            9 =>
                array('cateid' => '10', 'title' => 'cc_0', 'parentid' => '9', 'createtime' => '1527859627'),
            10 =>
                array('cateid' => '11', 'title' => 'd', 'parentid' => '0', 'createtime' => '1527859687'),
            11 =>
                array('cateid' => '12', 'title' => 'dd_0', 'parentid' => '11', 'createtime' => '1527859712',),
            12 =>
                array('cateid' => '13', 'title' => 'dd_1', 'parentid' => '11', 'createtime' => '1527859768',),
            13 =>
                array('cateid' => '14', 'title' => 'ddd', 'parentid' => '13', 'createtime' => '1527860067',),
        );
        return $data;
    }
}

$cate = new Cate();
$cate->index();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值