PHP - 数组引用树,第一次附加到新数组丢失

发布于 2024-10-01 11:42:36 字数 1998 浏览 0 评论 0原文

我有一个由嵌套关联数组组成的树结构。我有一组要添加到树中的路径,其中路径中的每个元素都是节点的名称。下面的代码应在“a”下创建节点“2”(确实如此),并在“2”下创建节点“i”、“ii”和“iii”。但由于某种原因,在“2”下创建的第一个节点丢失了。它将打印它正在创建,但 print_r 仅显示“ii”和“iii”。

$tree = array(
    name => 'root',
    children => array(
        array(
            name => 'a',
            children => array( ),
        ),
    ),
);


$paths = array(
    array('a','2','i'),
    array('a','2','ii'),
    array('a','2','iii'),
);


foreach ($paths as $path) {
    $node =& $tree;
    $found = true;
    while($found && count($path) > 0) {
        $name = $path[0];
        $found = false;
        echo "looking for $name\n";
        foreach ($node['children'] as &$child) {
            if($name == $child['name']) {
                echo "found $name\n";
                $node =& $child;
                $found = true;
                break;
            }
        }
        if($found) {
            array_shift($path);
        }
    }
    if(!$found) {
        echo "didn't find $name\n";
        while(count($path) > 0) {
            $name = array_shift($path);
            echo "creating $name in ".$node['name']."\n";
            $newNode = array(
                'name' => $name,
                'children' => array(),
            );
            $node['children'][] = $newNode;
            $node =& $newNode;
        }
    }
}

print_r($tree);

我怀疑问题与我如何初始化“2”的子级有关,因为它将在循环内创建,但我不知道我做错了什么。

编辑:所以我想出了如何让它工作......将最后一个内部循环从:更改

        $newNode = array(
            'name' => $name,
            'children' => array(),
        );
        $node['children'][] = $newNode;
        $node =& $newNode;

        $children =& $node['children'];
        $children[] = array(
            'name' => $name,
            'children' => array()
        );
        $node =& $children[count($children)-1];

似乎可以做到这一点,但我不确定为什么。需要一个很好的解释。

I have a tree structure composed of nested associative arrays. I have a set of paths that I want to add to the tree, where each element in the path is the name of a node. The code below should create the node "2" under "a" (which it does) and create the nodes "i", "ii" and "iii" under "2". For some reason though, the first node created under "2" gets lost. It will print that it's being created, but print_r only shows "ii" and "iii".

$tree = array(
    name => 'root',
    children => array(
        array(
            name => 'a',
            children => array( ),
        ),
    ),
);


$paths = array(
    array('a','2','i'),
    array('a','2','ii'),
    array('a','2','iii'),
);


foreach ($paths as $path) {
    $node =& $tree;
    $found = true;
    while($found && count($path) > 0) {
        $name = $path[0];
        $found = false;
        echo "looking for $name\n";
        foreach ($node['children'] as &$child) {
            if($name == $child['name']) {
                echo "found $name\n";
                $node =& $child;
                $found = true;
                break;
            }
        }
        if($found) {
            array_shift($path);
        }
    }
    if(!$found) {
        echo "didn't find $name\n";
        while(count($path) > 0) {
            $name = array_shift($path);
            echo "creating $name in ".$node['name']."\n";
            $newNode = array(
                'name' => $name,
                'children' => array(),
            );
            $node['children'][] = $newNode;
            $node =& $newNode;
        }
    }
}

print_r($tree);

I suspect the problem has to do with how I'm initializing the children of "2", since it will be created inside the loop, but I don't know what I'm doing wrong.

EDIT: So I figured out how to make it work... Changing that last inner loop from:

        $newNode = array(
            'name' => $name,
            'children' => array(),
        );
        $node['children'][] = $newNode;
        $node =& $newNode;

to

        $children =& $node['children'];
        $children[] = array(
            'name' => $name,
            'children' => array()
        );
        $node =& $children[count($children)-1];

seems to do it, but I'm not sure why. A good explanation is due.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

雨夜星沙 2024-10-08 11:42:36

所有这些引用都在伤害我的大脑,但是我可以看到一个明显的错误:

$node['children'][] = $newNode;
$node =& $newNode;

第二行用对 $newNode 的引用覆盖 $node,所以第一行未使用。

在新版本中,您将创建 $children 数组,进行操作,然后设置 $node 引用,这就是它起作用的原因。

All those references are hurting my brain, however there is one obvious error I can see in:

$node['children'][] = $newNode;
$node =& $newNode;

The second line overwrites $node with a reference to $newNode, so the first line is unused.

In your new version, you're creating the $children array, making the manipulation and then setting the $node reference, which is why it works.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文