PHP – рекурсивный многомерный матричный итератор

Я пытаюсь написать рекурсивную функцию итератора массива, в которой функция вернет результирующий набор всех наборов, заданных '$ needle'. Где $ needle = key

Вот моя функция:

function recursive($needle, $array, $holder = array()) { foreach ($array as $key => $value) { if (gettype($value) == 'array') { if ($key != $needle) { recursive($needle, $value); } elseif ($key == $needle) { if (!empty($value)) { array_push($holder, $value); } } } } return $holder; } 

Но я не получаю все результаты и получаю несколько пустых результатов, если я не укажу значение !empty($value) , хотя входной массив не имеет пустых наборов. Что я делаю не так?

Вам не нужно изобретать колесо, поскольку PHP имеет стандартный рекурсивный API-интерфейс Iterator :

 //$array is your multi-dimensional array $result = []; $search = 'foo'; $iterator = new RecursiveIteratorIterator( new RecursiveArrayIterator( $array, RecursiveArrayIterator::CHILD_ARRAYS_ONLY ) ); foreach($iterator as $key=>$value) { if($search==$key && $value!=='') { $result[] = $value; } } 

-номер, что, поскольку вы ищете значение по ключевым словам, в общем случае $value будет содержать весь подраздел.

Если вы хотите сделать это в своей собственной рекурсивной функции, вот что:

 function recursive($needle, $array, $holder = []) { $holder = []; foreach($array as $key=>$value) { if($key===$needle && $value!=='') { $holder = array_merge($holder, [$value]); } if(is_array($value)) { $holder = array_merge($holder, recursive($needle, $value, $holder)); } } return $holder; } 

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

 $needle = '0'; $array = [[1]]; $it = new KeyFilter( new RecursiveIteratorIterator( new MyRecursiveArrayIterator($array) , RecursiveIteratorIterator::SELF_FIRST ) , $needle ); $result = iterator_to_array($it, FALSE); var_dump($result); 

Приведение примерного результата в виде:

 array(2) { [0] => array(1) { [0] => int(1) } [1] => int(1) } 

Полный пример кода ( демонстрация ):

 <?php /** * @link http://stackoverflow.com/q/19709410/367456 */ Class MyRecursiveArrayIterator extends ArrayIterator implements RecursiveIterator { public function hasChildren() { $current = $this->current(); return is_array($current) && count($current); } public function getChildren() { return new self($this->current()); } } class KeyFilter extends RegexIterator { public function __construct(Iterator $iterator, $key) { parent::__construct( $iterator, '/' . preg_quote($key) . '/', NULL, RegexIterator::USE_KEY ); } } $needle = '0'; $array = [[1]]; $it = new KeyFilter( new RecursiveIteratorIterator( new MyRecursiveArrayIterator($array) , RecursiveIteratorIterator::SELF_FIRST ) , $needle ); $result = iterator_to_array($it, FALSE); var_dump($result); 

Крошечная модификация вашей конструкции:

$holder = recursive($needle, $value, $holder);

Ау?