[英]PHP: Convert an array with a path attribute to a tree structure
可以说,我有以下数组:
$array = array(
array(
"id" => 1,
"name" => "Europe",
"path" => "/"
),
array(
"id" => 2,
"name" => "Germany",
"path" => "/1/"
),
array(
"id" => 3,
"name" => "France",
"path" => "/1/"
),
array(
"id" => 4,
"name" => "Berlin",
"path" => "/1/2/"
),
array(
"id" => 5,
"name" => "Munich",
"path" => "/1/2/"
)
);
如您所见,它是一个多维数组,在earch 2级数组中具有3个属性:id,名称和路径。 该路径是基于其父代的parent-id的路径结构。 例如,德国(id = 2)属于欧洲,因此路径为“ / 1 /”(ID 1 =欧洲),德国柏林的路径为“ / 1/2 /”,表示“ / Europe / Germany /“
现在,我正在尝试以此创建一个树形数组,它看起来应该像这样:
$result = array(
1 => array(
"id" => 1,
"name" => "Europe",
"path" => "/",
"childs" => array(
2 => array(
"id" => 2,
"name" => "Germany",
"path" => "/1/",
"childs" => array(
4 => array(
"id" => 4,
"name" => "Berlin",
"path" => "/1/2/"
),
5 => array(
"id" => 5,
"name" => "Munich",
"path" => "/1/2/"
)
)
),
3 => array(
"id" => 3,
"name" => "France",
"path" => "/1/"
)
)
)
);
我已经尝试用内部引用创建一个函数,但这对我不起作用:
public static function pathToTree($items) {
$array = array();
$result = array();
foreach($items AS $res) {
$ids = explode("/", ltrim($res["path"] . $res["id"], "/"));
$count = count($ids);
$tmp = &$result;
foreach( $ids AS $id) {
if($count == 1) {
$tmp = $res;
$tmp["childs"] = array();
$tmp = &$tmp["childs"];
}
else {
$tmp[$id] = array(
"childs" => array()
);
$tmp = &$tmp[$id]["childs"];
}
$count--;
}
}
return $array;
}
好的,我想我刚刚找到了一个解决方案:
function pathToTree($array){
$tree = array();
foreach($array AS $item) {
$pathIds = explode("/", ltrim($item["path"], "/") . $item["id"]);
$current = &$tree;
foreach($pathIds AS $id) {
if(!isset($current["childs"][$id])) $current["childs"][$id] = array();
$current = &$current["childs"][$id];
if($id == $item["id"]) {
$current = $item;
}
}
}
return $tree["childs"];
}
这是针对1-n深度的动力学解决方案。 在http://ideone.com/gn0XLp上查看我的示例。 在这里,我在一定程度上进行了测试:
正如我在评论中所说,您至少需要三个循环才能实现目标。 功能如下:
function pathToTree($array){
$tree = Array();
for($i=0; $i < count($array); $i++){
if(substr_count($array[$i]["path"], '/') == 1)
$tree[$array[$i]["id"]] = $array[$i];
}
for($i=0; $i < count($array); $i++){
if(substr_count($array[$i]["path"], '/') == 2){
$num = (int)str_replace("/","",$array[$i]["path"]);
$tree[$num]["childs"][$array[$i]["id"]] = $array[$i];
}
}
for($i=0; $i < count($array); $i++){
if(substr_count($array[$i]["path"], '/') == 3){
$num = explode("/", $array[$i]["path"]);
$tree[$num[1]]["childs"][$num[2]]["childs"][$array[$i]["id"]] = $array[$i];
}
}
return $tree;
}
例:
考虑以下数组:
$array = array(
array(
"id" => 1,
"name" => "Europe",
"path" => "/"
),
array(
"id" => 2,
"name" => "Germany",
"path" => "/1/"
),
array(
"id" => 3,
"name" => "France",
"path" => "/1/"
),
array(
"id" => 4,
"name" => "Berlin",
"path" => "/1/2/"
),
array(
"id" => 5,
"name" => "Munich",
"path" => "/1/2/"
),
array(
"id" => 6,
"name" => "Asia",
"path" => "/"
),
array(
"id" => 7,
"name" => "China",
"path" => "/6/"
),
array(
"id" => 8,
"name" => "Bangladesh",
"path" => "/6/"
),
array(
"id" => 9,
"name" => "Beijing",
"path" => "/6/7/"
),
array(
"id" => 10,
"name" => "Dhaka",
"path" => "/6/8/"
)
);
如果我运行此代码:
print_r(pathToTree($array));
输出将是:
Array
(
[1] => Array
(
[id] => 1
[name] => Europe
[path] => /
[childs] => Array
(
[2] => Array
(
[id] => 2
[name] => Germany
[path] => /1/
[childs] => Array
(
[4] => Array
(
[id] => 4
[name] => Berlin
[path] => /1/2/
)
[5] => Array
(
[id] => 5
[name] => Munich
[path] => /1/2/
)
)
)
[3] => Array
(
[id] => 3
[name] => France
[path] => /1/
)
)
)
[6] => Array
(
[id] => 6
[name] => Asia
[path] => /
[childs] => Array
(
[7] => Array
(
[id] => 7
[name] => China
[path] => /6/
[childs] => Array
(
[9] => Array
(
[id] => 9
[name] => Beijing
[path] => /6/7/
)
)
)
[8] => Array
(
[id] => 8
[name] => Bangladesh
[path] => /6/
[childs] => Array
(
[10] => Array
(
[id] => 10
[name] => Dhaka
[path] => /6/8/
)
)
)
)
)
)
这是phpfiddle链接 ,以防您自己尝试。
我创建了一个递归函数:
//数组
$array = array(
array(
"id" => 1,
"name" => "Europe",
"path" => "/"
),
array(
"id" => 2,
"name" => "Germany",
"path" => "/1/"
),
array(
"id" => 3,
"name" => "France",
"path" => "/1/"
),
array(
"id" => 4,
"name" => "Berlin",
"path" => "/1/2/"
),
array(
"id" => 5,
"name" => "Munich",
"path" => "/1/2/"
),
array(
"id" => 6,
"name" => "Asia",
"path" => "/"
),
array(
"id" => 7,
"name" => "India",
"path" => "/6/"
),
array(
"id" => 7,
"name" => "Mumbai",
"path" => "/6/7"
),
array(
"id" => 8,
"name" => "Delhi",
"path" => "/6/7"
),
);
//递归函数
function createTree($input, &$result = array(), $key = null) {
if ($key == "id") {
$result["temp"]["id"] = $input;
}
if ($key == "name") {
$result["temp"]["name"] = $input;
}
if ($key == "path") {
$result["temp"]["path"] = $input;
$levels = is_string($input) ? array_values(array_filter(explode('/', $input))) : null;
if ($input == "/") {
$result[$result["temp"]["id"]] = $result["temp"];
}
if (count($levels) == 1) {
$result[$levels[0]]["childs"][$result["temp"]["id"]] = $result["temp"];
}
if (count($levels) == 2) {
$result[$levels[0]]["childs"][$levels[1]]["childs"][$result["temp"]["id"]] = $result["temp"];
}
unset($result["temp"]);
}
if (is_array($input)) {
foreach($input as $key => $value) {
createTree($value, $result, $key);
}
}
return $result;
}
// 结果
array (
1 =>
array (
'id' => 1,
'name' => 'Europe',
'path' => '/',
'childs' =>
array (
2 =>
array (
'id' => 2,
'name' => 'Germany',
'path' => '/1/',
'childs' =>
array (
4 =>
array (
'id' => 4,
'name' => 'Berlin',
'path' => '/1/2/',
),
5 =>
array (
'id' => 5,
'name' => 'Munich',
'path' => '/1/2/',
),
),
),
3 =>
array (
'id' => 3,
'name' => 'France',
'path' => '/1/',
),
),
),
6 =>
array (
'id' => 6,
'name' => 'Asia',
'path' => '/',
'childs' =>
array (
7 =>
array (
'id' => 7,
'name' => 'India',
'path' => '/6/',
'childs' =>
array (
7 =>
array (
'id' => 7,
'name' => 'Mumbai',
'path' => '/6/7',
),
8 =>
array (
'id' => 8,
'name' => 'Delhi',
'path' => '/6/7',
),
),
),
),
),
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.