Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/241.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 基于父ID值将数组从一维转换为多维_Php_Arrays_Recursion_Multidimensional Array - Fatal编程技术网

Php 基于父ID值将数组从一维转换为多维

Php 基于父ID值将数组从一维转换为多维,php,arrays,recursion,multidimensional-array,Php,Arrays,Recursion,Multidimensional Array,我有一个表示多维数据的一维对象数组: array( array( "id" => 45, "parent_id" => null ), array( "id" => 200, "parent_id" => 45 ), array( "id" => 345, "parent_id" => 45 ), array(

我有一个表示多维数据的一维对象数组:

array(
    array(
        "id" => 45,
        "parent_id" => null
    ),
    array(
        "id" => 200,
        "parent_id" => 45
    ),
    array(
        "id" => 345,
        "parent_id" => 45
    ),
    array(
        "id" => "355",
        "parent_id" => 200
    )
);
如何将其转换为多维数组:

array(
    array(
        "id" => 45,
        "parent_id" => null,
        "children" => array(
            array(
                "id" => 200,
                "parent_id" => 45,
                "children" => array(
                    "id" => "355",
                    "parent_id" => 200
                )

            ),
            array(
                "id" => 345,
                "parent_id" => 45
            ),
        )
    ),
);
我觉得这可以减少到只有两个循环(结合第二个和第三个),但现在我不能为我的生活找出如何


注意此函数依赖于
parent\u id
来处理没有父项为
NULL
或根本未设置的项目,因此
isset()
在最后一个循环中返回
FALSE

以下代码示例将数组
$array
转换为您要查找的树结构:

// key the array by id
$keyed = array();
foreach($array as &$value)
{
    $keyed[$value['id']] = &$value;
}
unset($value);
$array = $keyed;
unset($keyed);

// tree it
$tree = array();
foreach($array as &$value)
{
    if ($parent = $value['parent_id'])
        $array[$parent]['children'][] = &$value;
    else
        $tree[] = &$value;
}
unset($value);
$array = $tree;
unset($tree);

var_dump($array); # your result
如果存在
0
的现有父id,则此操作无效。但可以很容易地改变以反映这一点

这是一个相关的问题,因为原始数组已经设置了键,所以可以保留解决方案的前半部分:

编辑:

那么这是如何工作的呢?这是利用PHP变量别名(也称为)和(临时)数组来存储a)节点别名(
$keyed
)和b)构建新的树顺序(
$tree

你能[…]解释一下
$array=$keyed
$array=$tree
和unset的用途吗

由于
$keyed
$tree
都包含对
$array
中值的引用,我首先将该信息复制到
$array
中,例如:

$array = $keyed;
由于现在仍设置了
$keyed
(并且包含对与
$array
中相同值的引用),
$keyed
未设置:

unset($keyed);
这将取消设置
$keyed
中的所有引用,并确保不再引用
$array
中的所有值(该值的引用计数减少1)

如果在迭代之后没有取消设置临时数组,那么它们的引用仍然存在。如果在
$array
上使用
var\u dump
,您将看到所有值前面都有一个
&
,因为它们仍然被引用
unset($keyed)
删除这些引用,
var\u dump($array)
再次,您将看到
&
消失了

我希望这是可以理解的,如果你不流利的话,参考资料有时很难理解。它经常帮助我把它们看作变量别名

如果你想做一些运动,请考虑以下事项:

如何通过每次迭代将
$array
从平面转换为树


请自行决定何时单击包含数据的链接。

是否按顺序排列数据,以便子项始终位于父项之后?@Blem,不是这样。顺便说一句,这是一个很好的问题。第三个循环取消所有项的设置:?它只取消设置未设置
parent\u id
或设置为
NULL
(因此
isset()
返回FALSE)的项。如果实际数据不是这样,则需要修改最后一个循环中的
If
,以便它使用没有父项的项所特有的条件。如果我在提供的示例数据上运行它,它将生成您期望的结果。谢谢Dave!这正是问题所在。我处理好了它,现在它似乎工作得很好。再次感谢!太棒了!你能添加注释来解释
$array=$keyed
$array=$tree
和未设置的目的吗?@Emanuil Rusev:我添加了一部分关于分配和未设置的内容。如果你愿意,还可以做点运动。让我知道;练习的解决方案实际上也是您问题的有效答案,因此可以将其添加到答案中,以供以后参考。@EmanuilRusev:在另一个问题中,我也回答了有关数组和引用的更多细节。也许你会感兴趣,所以我把它作为评论放在这里。
unset($keyed);