假设我在PHP中有一个看起来像这样的数组
array
(
array(0)
(
array(0)
(
.
.
.
)
.
.
array(10)
(
..
)
)
.
.
.
array(n)
(
array(0)
(
)
)
)
我需要将这个多维数组的所有叶子元素都放到一个线性数组中,如何在不使用递归的情况下这样做呢?
function getChild($element)
{
foreach($element as $e)
{
if (is_array($e)
{
getChild($e);
}
}
}
注意:上面的代码片段,可怕的未完成
更新:数组的例子
Array
(
[0] => Array
(
[0] => Array
(
[0] => Seller Object
(
[credits:private] => 5000000
[balance:private] => 4998970
[queueid:private] => 0
[sellerid:private] => 2
[dateTime:private] => 2009-07-25 17:53:10
)
)
)
...剪断。
[2] => Array
(
[0] => Array
(
[0] => Seller Object
(
[credits:private] => 10000000
[balance:private] => 9997940
[queueid:private] => 135
[sellerid:private] => 234
[dateTime:private] => 2009-07-14 23:36:00
)
)
....snipped....
)
)
答案 0 :(得分:11)
实际上,有一个功能可以解决问题,请查看手册页:http://php.net/manual/en/function.array-walk-recursive.php
从页面改编的快速片段:
$data = array('test' => array('deeper' => array('last' => 'foo'), 'bar'), 'baz');
var_dump($data);
function printValue($value, $key, $userData)
{
//echo "$value\n";
$userData[] = $value;
}
$result = new ArrayObject();
array_walk_recursive($data, 'printValue', $result);
var_dump($result);
答案 1 :(得分:6)
您可以使用迭代器,例如:
$result = array();
foreach(new RecursiveIteratorIterator(new RecursiveArrayIterator($array), RecursiveIteratorIterator::LEAVES_ONLY) as $value) {
$result[] = $value;
}
答案 2 :(得分:2)
试试这个:
function getLeafs($element) {
$leafs = array();
foreach ($element as $e) {
if (is_array($e)) {
$leafs = array_merge($leafs, getLeafs($e));
} else {
$leafs[] = $e;
}
}
return $leafs;
}
编辑显然您不需要递归解决方案。所以这是一个使用堆栈的迭代解决方案:
function getLeafs($element) {
$stack = array($element);
$leafs = array();
while ($item = array_pop($stack)) {
while ($e = array_shift($item)) {
if (is_array($e)) {
array_push($stack, array($item));
array_push($stack, $e);
break;
} else {
$leafs[] = $e;
}
}
}
return $leafs;
}
答案 3 :(得分:2)
使用堆栈:
<?php
$data = array(array(array("foo"),"bar"),"baz");
$results = array();
$process = $data;
while (count($process) > 0) {
$current = array_pop($process);
if (is_array($current)) {
// Using a loop for clarity. You could use array_merge() here.
foreach ($current as $item) {
// As an optimization you could add "flat" items directly to the results array here.
array_push($process, $item);
}
} else {
array_push($results, $current);
}
}
print_r($results);
输出:
Array
(
[0] => baz
[1] => bar
[2] => foo
)
这应该比递归方法更有效。尽管我们在这里进行了大量的数组操作,但PHP具有写时复制语义,因此实际数据的实际zval不会在内存中重复。
答案 4 :(得分:1)
没有展平功能直接获得叶子。如果有更多的数组子项,只有当你到达底部将元素移动到结果平面数组时,你必须使用递归来检查每个数组。
答案 5 :(得分:1)
刚刚遇到同样的问题并使用了另一种未提及的方法。接受的答案要求ArrayObject
class正常工作。可以使用array
原语和anonymous function中的use
关键字(PHP&gt; = 5.3)来完成:
<?php
$data = array(
array(1,2,3,4,5),
array(6,7,8,9,0),
);
$result = array();
array_walk_recursive($data, function($v) use (&$result) { # by reference
$result[] = $v;
});
var_dump($result);