gpt4 book ai didi

php - 如何在PHP中将这个MPTT数组转换成树结构?

转载 作者:可可西里 更新时间:2023-10-31 23:26:37 25 4
gpt4 key购买 nike

我在数据库中有分层数据,存储在 Modified Preorder Tree Traversal 中格式。我在查询中提取数据,该查询类似于“SELECT ID, Left, Right, Name, etc FROM Table ORDER BY Left ;"。我正在尝试将此数据从 DB 给我的平面数组转换为树结构,然后我将使用 PHP 的 json_encode 函数将其输出为 JSON。

不过,我无法让我的树结构代码在第一层之外工作。这是一个最小的测试用例:

<pre><?php

function projectListToTree($projects) {
$stack = Array();
for($x =0; $x < count($projects); $x++) {
$project = $projects[$x];
$project['Children'] = Array();

while(count($stack) > 0 && $stack[count($stack) - 1]['Right'] < $project['Right']) {
array_pop($stack);
}

if(count($stack) > 0) {
$stack[count($stack) - 1]['Children'][] = $project;
echo "Adding " . $project['Name'] . " to " . $stack[count($stack) - 1]['Name'] . " for a total of "
. count($stack[count($stack) - 1]['Children']) . " kids\n";
} else {
echo "No parent\n";
}

echo "stack count: " . count($stack) . "\n";

array_push($stack, $project);
}

echo "Left in stack: " . count($stack) . "\n";

return $stack[0];
}

/*
This is basically what comes from the DB.
Should be:
Parent
First Child
Second Child
Grand Child
*/
$projects = Array(
Array(
"ID" => "2",
"Left" => "2",
"Right" => "9",
"ParentID" => "1",
"Name" => "Parent"
),
Array(
"ID" => "3",
"Left" => "3",
"Right" => "4",
"ParentID" => "2",
"Name" => "First Child"
),
Array(
"ID" => "4",
"Left" => "5",
"Right" => "8",
"ParentID" => "2",
"Name" => "Second Child"
),
Array(
"ID" => "5",
"Left" => "6",
"Right" => "7",
"ParentID" => "4",
"Name" => "Grand Child"
)
);


$tree = projectListToTree($projects);
echo "-----\n\n\n\n";
var_dump($tree);

?></pre>

这是我得到的输出:

No parent
stack count: 0
Adding First Child to Parent for a total of 1 kids
stack count: 1
Adding Second Child to Parent for a total of 2 kids
stack count: 1
Adding Grand Child to Second Child for a total of 1 kids
stack count: 2
Left in stack: 3
-----



array(6) {
["ID"]=>
string(1) "2"
["Left"]=>
string(1) "2"
["Right"]=>
string(1) "9"
["ParentID"]=>
string(1) "1"
["Name"]=>
string(6) "Parent"
["Children"]=>
array(2) {
[0]=>
array(6) {
["ID"]=>
string(1) "3"
["Left"]=>
string(1) "3"
["Right"]=>
string(1) "4"
["ParentID"]=>
string(1) "2"
["Name"]=>
string(11) "First Child"
["Children"]=>
array(0) {
}
}
[1]=>
array(6) {
["ID"]=>
string(1) "4"
["Left"]=>
string(1) "5"
["Right"]=>
string(1) "8"
["ParentID"]=>
string(1) "2"
["Name"]=>
string(12) "Second Child"
["Children"]=>
array(0) {
}
}
}
}

如您所见,“Grandchild”在某个地方迷路了,尽管 projectListToTree 函数中的输出似乎表明它应该在那里。似乎我扔给它的任何树结构都会掉落第二层以下的任何东西。对可能发生的事情有任何见解吗?

谢谢!

最佳答案

问题是分配一个数组并没有复制引用,而是复制了一个数组。这意味着,您在“父”节点的“ child ”中拥有的“第二个 child ”数组与您添加“孙子”的数组不同,而是它的副本。

要解决此问题,您必须明确使用引用分配而不是复制:

function projectListToTree($projects) {
$stack = Array();
for($x =0; $x < count($projects); $x++) {
$project = &$projects[$x];
$project['Children'] = array();

while(count($stack) > 0 && $stack[count($stack) - 1]['Right'] < $project['Right']) {
array_pop($stack);
}

if(count($stack) > 0) {
$stack[count($stack) - 1]['Children'][] = &$project;

echo "Adding " . $project['Name'] . " to " . $stack[count($stack) - 1]['Name'] . " for a total of "
. count($stack[count($stack) - 1]['Children']) . " kids\n";

echo "\n";
} else {
echo "No parent\n";
}

echo "stack count: " . count($stack) . "\n";

$stack[] = &$project;
}

echo "Left in stack: " . count($stack) . "\n";

return $stack[0];
}

请注意,在三个位置添加了一个符号。

由于这个问题,在 php 中使用嵌套数组和赋值运算符时必须格外小心。

这也意味着在嵌套数组中使用大量数据时,处理器使用率和内存占用量会很大。例如,在上面的例子中,当 projectListToTree() 返回时,完整的数组树被复制到局部变量 $tree 并且(因为 php 垃圾收集器很糟糕)在内存中两次。

关于php - 如何在PHP中将这个MPTT数组转换成树结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/823071/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com