需求描述:

现有一个节点集合

可以视为一个二维数组

 array(5) {
[0] => array(4) {
["id"] => string(1) "1"
["name"] => string(5) "Admin"
["title"] => string(12) "后台应用"
["pid"] => string(1) "0"
}
[1] => array(4) {
["id"] => string(1) "2"
["name"] => string(5) "Index"
["title"] => string(12) "前端应用"
["pid"] => string(1) "0"
}
[2] => array(4) {
["id"] => string(1) "3"
["name"] => string(5) "Index"
["title"] => string(12) "后台首页"
["pid"] => string(1) "1"
}
[3] => array(4) {
["id"] => string(1) "4"
["name"] => string(10) "MsgManager"
["title"] => string(12) "帖子管理"
["pid"] => string(1) "1"
}
[4] => array(4) {
["id"] => string(1) "5"
["name"] => string(4) "Rbac"
["title"] => string(10) "RBAC权限"
["pid"] => string(1) "1"
}
}

数组arr01

pid、level字段解释:

pid表示父级的id。取值范围{0,1,2,3,... ,n,...}
pid的值为0,表示这条记录不属于任何其他记录。

pid的值为1,表示这条记录属于id为1的记录。即为id为1的记录的子记录。

pid的值为2,表示这条记录属于id为2的记录。即为id为2的记录的子记录。

......

以此类推。

level表示层次、级别。取值范围{1,2,3},即为3个层次、或者是3个级别

level的值为1,表示第一层次,最高层次级,最高级别。

level的值为2,表示第二层次。
level的值为3,表示第三层次。

例如,如果level=1代表导航栏中的首页、公司部门、产品介绍等等
那么,level=2就代表部门A、部门B、...;产品A、产品B、产品C、... 这样,仅仅靠一个二维表,就能保存下各条记录的归属关系。 但是,为了使用foreach嵌套的方式循环输出有层次的数据,我们需要把原始的二维数组,按照归属关系组合到一起。 形如:一个多维数组
 array(2) {
[0] => array(5) {
["id"] => string(1) "1"
["name"] => string(5) "Admin"
["title"] => string(12) "后台应用"
["pid"] => string(1) "0"
["child"] => array(3) {
[0] => array(5) {
["id"] => string(1) "3"
["name"] => string(5) "Index"
["title"] => string(12) "后台首页"
["pid"] => string(1) "1"
["child"] => array(0) {
}
}
[1] => array(5) {
["id"] => string(1) "4"
["name"] => string(10) "MsgManager"
["title"] => string(12) "帖子管理"
["pid"] => string(1) "1"
["child"] => array(0) {
}
}
[2] => array(5) {
["id"] => string(1) "5"
["name"] => string(4) "Rbac"
["title"] => string(10) "RBAC权限"
["pid"] => string(1) "1"
["child"] => array(0) {
}
}
}
}
[1] => array(5) {
["id"] => string(1) "2"
["name"] => string(5) "Index"
["title"] => string(12) "前端应用"
["pid"] => string(1) "0"
["child"] => array(0) {
}
}
}

数组arr02

我们写一个递归函数node_merge()来实现:

 <?php
/**
* 递归重组节点信息多维数组
* @param [array] $node [要处理的节点数组:二维数组]
* @param [int] $pid [父级ID]
* @return [array] [树状结构的节点体系:多维数组]
*/
function node_merge($node,$pid=0){
$arr=array(); foreach ($node as $v) {
if ($v['pid']==$pid) {
$v['child']=node_merge($node,$v['id']);
$arr[]=$v;
}
} return $arr;
}
?>
怎么理解这个函数呢?

我们以处理原始的二维数组(arr01)的数据为例,通过调用node_merge()函数,转换成可直接看出归属关系的多维数组(arr02)。

函数中的$node即为arr01,当传入arr01数组时,$pid初始化为0值,函数新建一个临时数组(arr);

接着,用foreach循环,读取第一条记录(id=1那条记录),判断式处理:如果第一条记录中的父级id是0,那么正好等于初始化的$pid,

那么,在第一条记录中,加上一个字段(child)。第一条记录中的child字段的取值,来自pid=1的记录(想想为什么。提示:从node_merge($node,$v['id']);中的$v['id']入手)。

而取值操作是来自$arr[]=$v;这句命令。

这使用的是递归,函数调用函数,这是我的理解,如果你有更好的理解,可以给我留言。邮箱:1465567571@qq.com

ThinkPHP中:使用递归写node_merge()函数的更多相关文章

  1. Thinkphp中controller控制器根据curl函数请求数据

    public function member(){ $url="http://aitequn.tjnit.com/UserAction_findAllUser"; $ch =cur ...

  2. C#中的函数式编程:递归与纯函数(二)

    在序言中,我们提到函数式编程的两大特征:无副作用.函数是第一公民.现在,我们先来深入第一个特征:无副作用. 无副作用是通过引用透明(Referential transparency)来定义的.如果一个 ...

  3. Thinkphp中的 I 函数(Thinkphp3.2.3版本)

    I 函数的作用是获取系统变量,必要时还可以对变量值进行过滤及强制转化,I 函数的语法格式: I('变量类型.变量名/修饰符',['默认值'],['过滤方法或正则'],['额外数据源']) 一.获取变量 ...

  4. C#中的函数式编程:递归与纯函数(二) 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面

    C#中的函数式编程:递归与纯函数(二)   在序言中,我们提到函数式编程的两大特征:无副作用.函数是第一公民.现在,我们先来深入第一个特征:无副作用. 无副作用是通过引用透明(Referential ...

  5. 有一字符串,包含n个字符。写一函数,将此字符串中从第m个字符开始的全部字符复制成为另一个字符串。

    [提交][状态][讨论版] 题目描述 有一字符串,包含n个字符.写一函数,将此字符串中从第m个字符开始的全部字符复制成为另一个字符串. 输入 数字n 一行字符串 数字m 输出 从m开始的子串 样例输入 ...

  6. 面试题-->写一个函数,返回一个数组中所有元素被第一个元素除的结果

    package com.rui.test; import java.util.Random; /** * @author poseidon * @version 1.0 * @date:2015年10 ...

  7. HTML中直接写js 函数

    1.在HTML中直接写JS函数: <body onload="javascript:{window.location.href='http://www.baidu.com/'}&quo ...

  8. C语言:写一函数,将两个字符串中的元音字母复制到另一个字符串,然后输出

    题目描述 写一函数,将两个字符串中的元音字母复制到另一个字符串,然后输出. 输入 一行字符串 输出 顺序输出其中的元音字母(aeiuo) 样例输入 abcde 样例输出 ae 编码: #include ...

  9. 38 写一个函数,求一个字符串的长度,在main函数中输入字符串,并输出其长度。

    题目:写一个函数,求一个字符串的长度,在main函数中输入字符串,并输出其长度. public class _038PrintLength { public static void main(Stri ...

随机推荐

  1. 【实验吧】逆向rev50

    a simple reverse view 解题链接: http://ctf5.shiyanbar.com/reverse/rev50/rev50 看了别人写的wp得知是挂载参数执行. 补充:gdb挂 ...

  2. C# 根据Excel模版导出文件

    string fileName = Path.Combine(Application.StartupPath, "kfwh_yhxf.xls"); Microsoft.Office ...

  3. TTL转MIPI DSI芯片方案TC358778XBG

    型号:TC358778XBG功能:TTL转MIPI DSI通信方式:IIC分辨率:1920*1080电源:3.3/1.8/1.2封装形式:BGA80深圳长期现货 ,提供技术支持,样品申请及规格书请联系 ...

  4. 常用Dos操作指令

    1 dir 无参数:查看当前所在目录的文件和文件夹. /s:查看当前目录已经其所有子目录的文件和文件夹. /a:查看包括隐含文件的所有文件. /ah:只显示出隐含文件. /w:以紧凑方式(一行显示5个 ...

  5. 【DDD】领域驱动设计实践 —— 架构风格及架构实例

    概述 DDD为复杂软件的设计提供了指导思想,其将易发生变化的业务核心域放置在限定上下文中,在确保核心域一致性和内聚性的基础上,DDD可以被多种语言和多种技术框架实现,具体的框架实现需要根据实际的业务场 ...

  6. shell变量$(CURDIR),$0,$1,$2,$#含义解释

    $(CURDIR):   CURDIR是make的内嵌变量, 为当前目录 实例 SRCTREE := $(CURDIR) *$(CURDIR)为当前目录,相当于SRCTREE=./ MKCONFIG ...

  7. JavaScript学习日志(五):DOM

    一,基本定义 DOM是针对HTML和XML文档的API,根据W3C的HTML DOM标准,html文档中所以内容(无论是元素还是标签还是注释还是元素属性)都是节点. 二,Node类型:每一个节点都含有 ...

  8. TitleLayout——一个Android轻松实现标题栏的库

    TitleLayout 多功能.通用的.可在布局或者使用Java代码实现标题栏: 支持沉浸式状态栏: 支持左侧返回按钮不需要手动实现页面返回: 支持左侧按钮,中间标题,右边按钮点击 左侧支持图片+文字 ...

  9. c# List集合中First、Last、Single方法使用

    操作符 如果源序列是空的 源序列只包含一个元素 源序列包含多个元素 First 抛异常 返回该元素 返回第一个元素 FirstOrDefault 返回default(TSource) 返回该元素 返回 ...

  10. Lombok的使用

    下面介绍几个我常用的 lombok 注解:         @Data   :注解在类上:提供类所有属性的 getting 和 setting 方法,此外还提供了equals.canEqual.has ...