分层数据Hierarchical Data探索(1.递归)

栏目: PHP · 发布时间: 5年前

内容简介:什么是分层数据?类似于树形结构,除了根节点和叶子节点外,所有节点都有一个父节点和一个或多个子节点。大多数同学都曾在数据库中处理过分层数据(hierarchical data),分层数据存在于许多基于数据库的应用程序中,包括论坛和邮件列表中的分类、商业组织图表、内容管理系统的分类、产品分类、无限级分类、多级菜单、省份城市等等。但是因为关系数据库中的表没有层次关系,只是简单的平面化的列表;而分层数据具有父-子关系,显然关系数据库中的表不能自然地表现出其分层的特性。

分层数据Hierarchical Data探索(例如:无限级分类、多级菜单、省份城市)

引言

什么是分层数据?

类似于树形结构,除了根节点和叶子节点外,所有节点都有一个父节点和一个或多个子节点。

大多数同学都曾在数据库中处理过分层数据(hierarchical data),分层数据存在于许多基于数据库的应用程序中,包括论坛和邮件列表中的分类、商业组织图表、内容管理系统的分类、产品分类、无限级分类、多级菜单、省份城市等等。但是因为关系数据库中的表没有层次关系,只是简单的平面化的列表;而分层数据具有父-子关系,显然关系数据库中的表不能自然地表现出其分层的特性。

接下来我会先通过一般方法和递归( recursion )方法来实现无限极分类,然后再通过 两种数据模型 来谈一谈分层数据的处理。

三种方式的变量传递

  • & 引用赋值
function doloop1(&$i = 1)
{
    print_r($i);
    $i++;
    if ($i <= 10) {
        doloop1($i);
    }
}
doloop1();
  • static 静态变量
function doloop2()
{
    static $i = 1;
    print_r($i);
    $i++;
    if ($i <= 10) {
        doloop2();
    }
}

doloop2();
  • global 全局变量
$i = 1;
function doloop3()
{
    global $i;
    echo $i;
    $i++;
    if ($i <= 10) {
        doloop3();
    }
}
doloop3();

构建模拟数据

# 模拟数据
       $data = [
            ['id' => 1, 'title' => 'Electronics', 'parent_id' => 0],
            ['id' => 2, 'title' => 'Laptops & PC', 'parent_id' => 1],
            ['id' => 3, 'title' => 'Laptops', 'parent_id' => 2],
            ['id' => 4, 'title' => 'PC', 'parent_id' => 2],
            ['id' => 5, 'title' => 'Cameras & photo', 'parent_id' => 1],
            ['id' => 6, 'title' => 'Camera', 'parent_id' => 5],
            ['id' => 7, 'title' => 'Phones & Accessories', 'parent_id' => 1],
            ['id' => 8, 'title' => 'Smartphones', 'parent_id' => 7],
            ['id' => 9, 'title' => 'Android', 'parent_id' => 8],
            ['id' => 10, 'title' => 'iOS', 'parent_id' => 8],
            ['id' => 11, 'title' => 'Other Smartphones', 'parent_id' => 8],
            ['id' => 12, 'title' => 'Batteries', 'parent_id' => 7],
            ['id' => 13, 'title' => 'Headsets', 'parent_id' => 7],
            ['id' => 14, 'title' => 'Screen Protectors', 'parent_id' => 7],
        ];

获取无限极分类

/**
 * 值引用获取无限极分类树
 * 
 * @param array $data
 * @return array
 */
function make_tree($data)
{  
    $refer = array();  
    $tree = array();  
    foreach($data as $k => $v){  
        $refer[$v['id']] = & $data[$k];  //创建主键的数组引用  
    }  

    foreach($data as $k => $v){  
        $parent_id = $v['parent_id'];   //获取当前分类的父级id  
        if($parent_id == 0){  
            $tree[] = & $data[$k];   //顶级栏目
        }else{  
            if(isset($refer[$parent_id])){  
                $refer[$parent_id]['children'][] = & $data[$k];  //如果存在父级栏目,则添加进父级栏目的子栏目数组中  
            }  
        }  
    }  

    return $tree;  
}

/**
 * 递归获取无限极分类树
 * 
 * @param array $data
 * @param int $parent_id
 * @param int $level
 * @return array
 */
function make_tree2($data = [], $parent_id = 0, $level = 0)
{
    $tree = [];
    if ($data && is_array($data)) {
        foreach ($data as $v) {
            if ($v['parent_id'] == $parent_id) {
                $tree[] = [
                    'id' => $v['id'],
                    'level' => $level,
                    'title' => $v['title'],
                    'parent_id' => $v['parent_id'],
                    'children' => make_tree2($data, $v['id'], $level + 1),
                ];
            }
        }
    }
    return $tree;
}

获取子节点以及节点的层级

/**
 * 引用赋值方式
 * @param array $data
 * @param int $id
 * @param int $level
 * @return array
 */
function getSubTree($data = [], $id = 0, $level = 0)
{
    static $tree = [];

    foreach ($data as $key => $value) {
        if ($value['parent_id'] == $id) {
            $value['laravel'] = $level;
            $tree[] = $value;
            getSubTree($data, $value['id'], $level + 1);
        }
    }
    return $tree;
}

/**
 * 静态变量方式
 * @param array $data
 * @param int $id
 * @param int $level
 * @return array
 */
function getSubTree($data = [], $id = 0, $level = 0)
{
    static $tree = [];

    foreach ($data as $key => $value) {
        if ($value['parent_id'] == $id) {
            $value['laravel'] = $level;
            $tree[] = $value;
            getSubTree($data, $value['id'], $level + 1);
        }
    }
    return $tree;
}


/**
 * 全局变量方式
 * @param array $data
 * @param int $id
 * @param int $level
 * @return array
 */

$tree = [];  //先申明变量
function getSubTree($data = [], $id = 0, $level = 0)
{
    global $tree;

    foreach ($data as $key => $value) {
        if ($value['parent_id'] == $id) {
            $value['laravel'] = $level;
            $tree[] = $value;
            getSubTree($data, $value['id'], $level + 1);
        }
    }
    return $tree;
}

通过pid获取所有上级分类 常用于面包屑导航

/**
 * getParentsByParentId2($categories, 9)
 *
 * @param array $data
 * @param $parent_id
 * @return array
 */
function getParentsByParentId($data = [], $parent_id)
{
    static $categories = [];

    if ($data && is_array($data)) {
        foreach ($data as $item) {
            if ($item['id'] == $parent_id) {
                $categories[] = $item;
                getParentsByParentId($data, $item['parent_id']);
            }
        }
    }
    return $categories;
}

function getParentsByParentId2($data = [], $parent_id)
{
    $categories = [];

    if ($data && is_array($data)) {
        foreach ($data as $item) {
            if ($item['id'] == $parent_id) {
                $categories[] = $item;
                $categories = array_merge($categories, getParentsByParentId2($data, $item['parent_id']));
            }
        }
    }
    return $categories;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Computer Age Statistical Inference

Computer Age Statistical Inference

Bradley Efron、Trevor Hastie / Cambridge University Press / 2016-7-21 / USD 74.99

The twenty-first century has seen a breathtaking expansion of statistical methodology, both in scope and in influence. 'Big data', 'data science', and 'machine learning' have become familiar terms in ......一起来看看 《Computer Age Statistical Inference》 这本书的介绍吧!

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具