Пока, если мне нужно перебирать многомерный массив, я использую цикл foreach для каждого измерения.
например, для двух измерений
foreach($array as $key=>$value) { foreach($value as $k2=>$v2) { echo } }
Что мне делать, когда я не знаю глубину массива? т.е. глубина является переменной.
Единственное, что я могу придумать, это закодировать целый стек циклов и разбить цикл, если следующее значение не является массивом. Это кажется немного глупым.
Есть ли способ лучше?
Да, вы можете использовать рекурсию . Вот пример, когда вы выводите все элементы в массиве:
function printAll($a) { if (!is_array($a)) { echo $a, ' '; return; } foreach($a as $v) { printAll($v); } } $array = array('hello', array('world', '!', array('whats'), 'up'), array('?')); printAll($array);
То, что вы всегда должны помнить при выполнении рекурсии, – это то, что вам нужен базовый случай, когда вы не будете углубляться.
Мне нравится проверять базовый регистр перед продолжением функции. Это обычная идиома, но это не обязательно. Вы можете точно также проверить цикл foreach
если вы должны вывести или сделать рекурсивный вызов, но я часто считаю, что этот код будет сложнее поддерживать таким образом.
«Расстояние» между вашим текущим входом и базовым регистром называется вариантом и является целым числом. Вариант должен строго уменьшаться во всех рекурсивных вызовах. Вариантом в предыдущем примере является the depth of $a
. Если вы не думаете об этом варианте, вы рискуете получить бесконечные рекурсии, и, в конце концов, скрипт умрет из-за переполнения стека . Это не редкость, чтобы точно документировать, что этот вариант находится в комментарии перед рекурсивными функциями.
Вы можете использовать рекурсию для этой проблемы:
Вот один пример
$array = array(1 => array(1 => "a", 2 => array(1 => "b", 2 => "c", 3 => array(1 => "final value")))); //print_r($array); printAllValues($array); function printAllValues($arr) { if(!is_array($arr)) { echo '<br />' . $arr; return; } foreach($arr as $k => $v) { printAllValues($v); } }
Он будет использовать рекурсию для цикла через массив
Он будет печатать как
a b c final value