我有一个看起来像这样的数组
array(
1 => array(
'id' => 1,
'name' => 'first',
'parent' => null
),
2 => array(
'id' => 2,
'name' => 'second',
'parent' => null
),
3 => array(
'id' => 3,
'name' => 'third',
'parent' => 1
),
4 => array(
'id' => 4,
'name' => 'fourth',
'parent' => 3
),
5 => array(
'id' => 5,
'name' => 'fifth',
'parent' => 1
),
);
但我想将任何“子”项移动到数组下的“children”键。 所以,我想最终得到
array(
1 => array(
'id' => 1,
'name' => 'first',
'parent' => null,
'children' => array(
3 => array(
'id' => 3,
'name' => 'third',
'parent' => 1,
'children' => array(
4 => array(
'id' => 4,
'name' => 'fourth',
'parent' => 3,
'children' => array()
),
)
),
5 => array(
'id' => 5,
'name' => 'fifth',
'parent' => 1,
'children' => array()
)
)
),
2 => array(
'id' => 2,
'name' => 'second',
'parent' => null,
'children' => array()
)
);
但说实话,我完全不知道从哪里开始。
我想可能会循环遍历数组中的每个项目,然后在我使用$new_array[$current['parent']]['children'][$current['id']] = $current;
时构建新数组
但是一旦我点击嵌套项目,我就会遇到问题。
我可以构建一个接受当前数组的函数,整个数组以递归方式向上移动树来查找所有父节点,从而找到整个路径,但如果父节点之一尚未创建,我会再次遇到问题爱好。
我能想到的唯一选择是构建一个不同级别的父级的数组映射,并以递归的方式循环,然后抓住所有元素,但这看起来有点低效?
有人可以建议解决方案吗?
答案 0 :(得分:3)
你对foreach循环有正确的想法。但是,你想要做的事情需要引用的“魔力”。
foreach($oldArray as $key => &$item) {
if($item["parent"] == null) $newArray[$key] = &$item;
else $oldArray[$item["parent"]]["children"][$key] = &$item;
}
unset($item);
这将输出'$ oldArray'
Array
(
[1] => Array
(
[id] => 1
[name] => first
[parent] =>
[children] => Array
(
[3] => Array
(
[id] => 3
[name] => third
[parent] => 1
[children] => Array
(
[4] => Array
(
[id] => 4
[name] => fourth
[parent] => 3
)
)
)
[5] => Array
(
[id] => 5
[name] => fifth
[parent] => 1
)
)
)
[2] => Array
(
[id] => 2
[name] => second
[parent] =>
)
[3] => Array
(
[id] => 3
[name] => third
[parent] => 1
[children] => Array
(
[4] => Array
(
[id] => 4
[name] => fourth
[parent] => 3
)
)
)
[4] => Array
(
[id] => 4
[name] => fourth
[parent] => 3
)
[5] => Array
(
[id] => 5
[name] => fifth
[parent] => 1
)
)
对于newArray('纯化'版本)
Array
(
[1] => Array
(
[id] => 1
[name] => first
[parent] =>
[children] => Array
(
[3] => Array
(
[id] => 3
[name] => third
[parent] => 1
[children] => Array
(
[4] => Array
(
[id] => 4
[name] => fourth
[parent] => 3
)
)
)
[5] => Array
(
[id] => 5
[name] => fifth
[parent] => 1
)
)
)
[2] => Array
(
[id] => 2
[name] => second
[parent] =>
)
)
现在,为什么这样做: 通过将& item放入foreach循环,我们使用对项目的引用,而不是副本。这意味着,无论我们对该项目进行哪些更改,我们也会更改相应的数组元素。
通过将& $ item传递给$ newArray [$ key]或子数组,我们传递引用...所以无论我们对'原始对象'做什么(即[3]),我们也做所有参考。
unset($ item)是必需的,因为它会删除$ item的最后一个实例与变量之间的绑定。否则,只要我们再次更改$ item变量,我们也会更改最后一个变量。在这个剧本中并不完全必要,但仍然是一个很好的记忆。
答案 1 :(得分:0)
您可以将它们从数组转换为对象。这很容易做到,你几乎已经有了一个对象结构。
不同之处在于,您可以在每个对象中设置__construct()
函数,并将其作为参数传递给ID
个数字,并在您通过主数组查看的__construct()
函数内部对于子项并添加它们。当它添加到一个新的子项时,它会再次触发此子项中的__construct()
函数,该函数将再次在数组中搜索它自己的子项。
你最终可能会得到一个很好的物体,旁边没有工作。如果你想把它们作为一个数组放在最后,那么你可以使用一个函数将整个heirachy作为一个数组返回 - 但是无论如何你的对象不会更好吗?