/**
* 将父——子类列表转换为一维树形结构列表
* @param $list array 总数据列表
* @param $response array 顶级类列表
*
* @return array
*/
function array_tree($list, $response)
{
$len = count($response); // 统计顶级类个数
$level = [
0 => array_column($response, 'id'),
];
for ($i = 0; $i < $len; $i++) { // 循环顶级类
// 搜索当前类下的子类
$temp_child = search_data($list, 'parent_id', $response[$i]['id']);
// 排序搜索到的子类
array_multisort(array_column($temp_child, 'sort'), SORT_ASC, $temp_child);
// 拼接前缀符号
foreach ($temp_child as $c_k => $c_v) {
if ($c_v == end($temp_child)) {
$temp_child[$c_k]['pre_fix'] = "└"; // 结尾符
// $temp_child[$c_k]['title'] = "└".$temp_child[$c_k]['title']; ─
} else {
$temp_child[$c_k]['pre_fix'] = "├"; // 除开结尾的符号
// $temp_child[$c_k]['title'] = "├".$temp_child[$c_k]['title'];
}
}
// 将子类添加到父类的后面
array_splice($response, $i + 1, 0, $temp_child);
$len += count($temp_child); // 加上添加的子类长度
// 循环判断等级
foreach ($level as $level_k => $level_v) {
// 如果当前父级id存在于当前等级数组,则将当前id添加到下一个等级的数组中
if (in_array($response[$i]['parent_id'], $level_v)) {
// 判断等级数组是否存在,如果不存在则新增
if (array_key_exists($level_k + 1, $level)) {
// 存在,则直接添加
array_push($level[$level_k + 1], $response[$i]['id']);
} else {
// 不存在,则添加一个数组
array_push($level, [$response[$i]['id']]);
}
// 向前缀之前添加空格,体现层级关系
if ($level_k > 0) {
$response[$i]['pre_fix'] = str_repeat(" ", $level_k) . $response[$i]['pre_fix'];
}
}
}
}
return $response;
}
array_multisort()函数用法请见:在数组中根据指定的条件进行搜索
array_multisort()函数用法请见:PHP二维数组中,根据指定键值排序
示例:
$list = [
['id' => 1, 'title' => '测试1', 'parent_id' => 0],
['id' => 2, 'title' => '测试2', 'parent_id' => 0],
['id' => 3, 'title' => '测试3', 'parent_id' => 0],
['id' => 4, 'title' => '测试4', 'parent_id' => 0],
['id' => 5, 'title' => '测试-子1', 'parent_id' => 1],
['id' => 6, 'title' => '测试-子2', 'parent_id' => 2],
['id' => 7, 'title' => '测试5', 'parent_id' => 0],
['id' => 8, 'title' => '测试-子3', 'parent_id' => 1],
['id' => 9, 'title' => '测试-子2-1', 'parent_id' => 6],
['id' => 10, 'title' => '测试-子1-1', 'parent_id' => 5],
];
// 获取顶级列表
$top_list = search_data($list, 'parent_id', 0);
//
array_multisort(array_column($top_list, 'sort'), SORT_ASC, $top_list);
$res = array_tree($list, $top_list);
结果:
测试1
├测试-子1
└测试-子1-1
└测试-子3
测试2
└测试-子2
└测试-子2-1
测试3
测试4
测试5
/**
* @param array $list 源数组
* @param string $pk 数据主键id
* @param string $pid 上级数据关联信息 存储的标识
* @param string $child 子集合 键
* @param int $root 父级的 上一级 关联数据值
* @return array
* 上下级关系的 二维数组 转为树状结构
*/
function listGoTree(array $list = [], $pk = 'id', $pid = 'pid', $child = '_child', $root = 0)
{
// 创建Tree
$tree = array();
if (is_array($list)) {
// 创建基于主键的数组引用
$refer = array();
foreach ($list as $key => $data) {
$refer[$data[$pk]] = &$list[$key];
}
foreach ($list as $key => $data) {
// 判断是否存在parent
$parentId = $data[$pid];
if ($root == $parentId) {
$tree[] = &$list[$key];
} else {
if (isset($refer[$parentId])) {
$parent = &$refer[$parentId];
// $list[$key]['name']='—'.$list[$key]['name'];
$parent[$child][] = &$list[$key];
}
}
}
}
return $tree;
}