Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/280.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数组递归_Php_Arrays_Recursion - Fatal编程技术网

php数组递归

php数组递归,php,arrays,recursion,Php,Arrays,Recursion,我有这样一个数组: Array ( [0] => Array ( [id] => 1000 [enroller_id] => 1005) [1] => Array ( [id] => 1005 [enroller_id] =>) [2] => Array ( [id] => 1101 [enroller_id] => 1000 ) [3] => Array ( [id] => 1111 [enroller_id] =

我有这样一个数组:

Array ( 
[0] => Array ( [id] => 1000 [enroller_id] => 1005) 

[1] => Array ( [id] => 1005 [enroller_id] =>) 

[2] => Array ( [id] => 1101 [enroller_id] => 1000 ) 

[3] => Array ( [id] => 1111 [enroller_id] => 1000 ) 
)
Array(
[1005] => Array(
               [1000] => Array(
                              [1101] => ...
                              [1111] => ...
                              )
               )
)
我想创建如下层次结构数组:

Array ( 
[0] => Array ( [id] => 1000 [enroller_id] => 1005) 

[1] => Array ( [id] => 1005 [enroller_id] =>) 

[2] => Array ( [id] => 1101 [enroller_id] => 1000 ) 

[3] => Array ( [id] => 1111 [enroller_id] => 1000 ) 
)
Array(
[1005] => Array(
               [1000] => Array(
                              [1101] => ...
                              [1111] => ...
                              )
               )
)
你能帮我吗?我认为这是一个递归

//$paths is an array of references, in which _every_ item will sit at 'root'
//level, but also as a reference as a child to it's parent.

//initialize location of parentless / root items:
$paths = array('N'=>array());

foreach($items as $item){
    //$target is the parent-id, or 'N' if we are a root node
    $target = isset($item['enroller_id']) && !empty($item['enroller_id']) ? $item['enroller_id'] :'N';

    //if the parent is not yet in the paths array, make an entry for it
    if(!isset($paths[$target]))      $paths[$target] = array();

    //if this item is not yet in the array (the previous statement could  
    //already have inserted it, make an array(
    if(!isset($paths[$item['id']]))  $paths[$item['id']] = array();

    //add the current item as a reference to it's parent
    $paths[$target][$item['id']] =  &$paths[$item['id']];

    //Setting it as a reference has this consequence:
    //   when adding an item to the $paths[$id] array, it will 
    //   automatically be added to $paths[$parent][$id], as 
    //   both $paths[$id] & $paths[$parent][$id] point to the same
    //   location in memory.
    //   This goes to infinite depth: if $foo is a child of $id, and you
    //   add a node to it, it will be in
    //   $paths[$foo]               = array($child);
    //   $paths[$id][[$foo]         = array($child);
    //   $paths[$parent][$id][$foo] = array($child);
    //
    //   Altering an item at any location in paths / the tree will alter it anywhere
    //   in the paths / tree, unsetting it anywhere only unset the data at that location, 
    //   other locations will still have the same data (and the data will keep 
    //   existing until the last reference is unset())

}
//we are only interested in the 'root' nodes (all other nodes should be subnodes
//in this tree
$tree = $paths['N'];
//remove all unused references in the $paths array
//do remember to do this: cleaning up references is important
unset($paths);
//tree is now an array of 'normal' values (i.e. only 1 reference to each datapoint exists
var_dump($tree);

不要忘记取消设置路径:如果不小心,引用可能会导致难以跟踪的错误。

这将满足您的需要,但它不会将第一个元素(1005)放入数组:

function create_array($number, $data)
{
    $result = array();
    foreach ($data as $row)
    {
        if ($row['enroller_id'] == $number)
        {
            $result[$row['id']] = create_array($row['id'], $data);
        }
    }
    return $result;
}

print_r(create_array(1005, $data));
输出:

Array
(
    [1000] => Array
        (
            [1101] => Array ()
            [1111] => Array ()
        )
)

谢谢这是理想的解决方案!我们如何神奇地知道1005?它不应该出现在结果中吗?1005应该替换为null,然后它就可以工作了。通常情况下,递归很简单,但会导致过度迭代。+1,伟大的递归现在我可以轻松创建动态嵌套数组。它只是在每次迭代中链接当前节点和其父节点。首先,您只有两个孤立节点。最终,它们联系在一起,直到你得到最后一棵树。唯一的副作用是未植根的节点将被默默地忽略,但这并不是算法的真正错误。在解决方案中添加了注释以进行解释@亚历山大布鲁托夫:能告诉我为什么吗?没有数据重复,只有一个循环,非常有效,并且在最后没有引用。作为一个额外的奖励,物品的顺序并不重要:你可以在输入中有一个孩子在父母之前很久,而且它仍然有效。这不是很明确。虽然这个解决方案很难理解,但它只在数组中循环一次。如果你有一棵大树,这使得它比递归解决方案快得多。拥有一个快速应用程序的最好方法是使用适当的算法。这是我想到的第一个解决办法。看起来几乎微不足道……如果一个人不知道什么是参考文献,那么它就不是“清晰的”。遗憾的是,PHP程序员并不总是这样,但我认为他们应该知道这些。不理解一门语言的基本知识并不是我个人改变答案的理由。是的,编写清晰易读的代码,可以对代码进行较小的性能测试,以使代码更加清晰和易于维护,但我认为这里的情况并非如此。