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程序员并不总是这样,但我认为他们应该知道这些。不理解一门语言的基本知识并不是我个人改变答案的理由。是的,编写清晰易读的代码,可以对代码进行较小的性能测试,以使代码更加清晰和易于维护,但我认为这里的情况并非如此。