php递归生成树
最近开发过程中遇到一个小问题,要求将一些数据转换为树形结构,类似于
[
'name' => 'root',
'children' => [
[
'name' => 'first',
'children' => [
[
'name' => 'first-first',
'children' => []
],
[
'name' => 'first-two',
'children' => []
],],
],
[
'name' => 'two',
'children' => [
[
'name' => 'two-first',
'children' => []
],
[
'name' => 'two-two',
'children' => []
],],
]
]];
提供的数据结构是这种类型

看上去是个树形结构,再结合前面的数据格式,所以脑海中很简单的就冒出了方法——用递归。
虽然之前写过一些递归,但真正用于这种项目还是头一次,当中也是遇到不少错误,所以算法以及数据结构扎实还是很有必要的。
关于递归之类的定义就不多说了,简单来说就是分而治之,大事化小,小事化了这种,所以,我们从最简单的开始考虑,这里采用的是自底向上的方式建立树
1.如何处理 最后一列的数据,即将其变为一个数组
看上面这个数据结构,似乎有点头疼?没关系,只要忽略掉其他不必要的东西就行
现在,数据结构在我们眼中是这个样子

现在,问题是不是一下子简单起来?
那么,这是我的代码
$data = '
电话沟通
电子邮件沟通
短信沟通
移动平台沟通
其他沟通方式';
$data = explode("\r\n", $data);
$newData = [];
foreach ($data as $v)
{
$newData[] = [
'name' => $v,
'children' => []
];
}
print_r($newData);
特别注意其中的”\r\n”,不要使用单引号,单引号当中的数据是不会被转义的
php的数组十分强大,所以这里我将其分割为数组,方便处理,接着就是日常操作了,跑个循环就出来了
2.第二步,如何处理有级联的

现在,我们眼中的数据结构是这样的
如何处理?继续用for循环?似乎有点难处理,那么,这个时候就是递归的出现了
或许你会有其他、更好的想法, 但是我的代码是这样的
/**
* @param $data
* @param $index
* @return array
*/
function recursive(&$data, $index)
{
$temp = [];
while (true)
{
$str = next($data);
if (!$str)
return $temp;
$currentIndex = 0;
$str = str_replace("\t", '', $str, $currentIndex);
if ($currentIndex <= $index)
{
prev($data);
return $temp;
}
$temp[] = [
'children' => recursive($data, $currentIndex),
'name' => $str,
];
}
}
$data = '
沟通方式
电话沟通
电子邮件沟通
短信沟通
移动平台沟通
其他沟通方式
销售方式';
$data = explode("\r\n", $data);
print_r(recursive($data, -1));
突然有些头大?那就对了——容我慢慢道来
首先如何解决读取数据的问题?
在这里我通过php数组自带的next和prev控制着数组,来获取每条数据
接着,替换掉前面tab符号,currentIndex用于记录是第几级,整个函数最重要的部分是这段
if ($currentIndex <= $index)
{
prev($data);
return $temp;
}
这段用于第三级别与第二级之间的过渡,如果不使用prev($data);
那么 “其他沟通方式”的children 中就会包含 “销售方式”
造成层级不对,之后就是递归的常规操作,调用自己
其中你可能注意到,最开始调用的时候传递的index 是 -1
print_r(recursive($data, -1));
这样可以可以防止第一个 沟通方式 被跳过
如此,可能会比较绕,但逻辑上还是挺清晰的,建议有迷惑的同学可以自己断点,一步步查看
sb ba ni
????