Я пытаюсь написать рекурсивную функцию итератора массива, в которой функция вернет результирующий набор всех наборов, заданных '$ 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);
Ау?