Извлечь листовые узлы многомерного массива в PHP

Предположим, у меня есть массив в 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.... ) 

)

На самом деле, есть одна функция, которая будет делать трюк, проверьте страницу руководства по адресу: 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); 

Вы можете использовать итераторы, например:

 $result = array(); foreach(new RecursiveIteratorIterator(new RecursiveArrayIterator($array), RecursiveIteratorIterator::LEAVES_ONLY) as $value) { $result[] = $value; } 

Используйте стек:

 <?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 имеет семантику copy-on-write, поэтому фактические zvals реальных данных не будут дублироваться в памяти.

Попробуй это:

 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; } 

Нет никакой функции сглаживания, чтобы получить прямые листья. Вы должны использовать рекурсию, чтобы проверять каждый массив, если имеет больше дочерних элементов массива, и только когда вы добираетесь до нижней части, чтобы переместить элемент в плоский массив результатов.

Просто получил ту же проблему и использовал другой метод, который не упоминался. Принятый ответ требует, ArrayObject класс ArrayObject работал правильно. Это можно сделать с помощью примитива array и ключевого слова use в анонимной функции (PHP> = 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);