2012-06-07 142 views
8

Hasta ahora, si tengo que recorrer una matriz multidimensional, uso un ciclo foreach para cada dimensión.¿Hay alguna manera de recorrer una matriz multidimensional sin saber su profundidad?

por ejemplo de dos dimensiones

foreach($array as $key=>$value) 
{ 
    foreach($value as $k2=>$v2) 
    { 
     echo 
    } 
} 

¿Qué hago cuando no sé la profundidad de la matriz? es decir, la profundidad es variable.

Lo único que se me ocurre es codificar una pila completa de bucles y romper el bucle si el siguiente valor no es una matriz. Esto parece un poco tonto.

¿Hay una manera mejor?

Respuesta

16

Sí, puede usar recursion. He aquí un ejemplo de salida donde todos los elementos de un array:

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

Lo que debe siempre recordar la hora de hacer la recursividad es que se necesita un caso base de donde no ir más profundo.

Me gusta comprobar la carcasa base antes de continuar con la función. Esa es una expresión común, pero no es estrictamente necesaria. También puede verificar en el circuito foreach si debe realizar una salida o hacer una llamada recursiva, pero a menudo el código es más difícil de mantener de esa manera.

La "distancia" entre su entrada actual y el caso base se llama variante y es un número entero. La variante debe ser estrictamente decreciente en cada llamada recursiva. La variante en el ejemplo anterior es the depth of $a. Si no piensas en la variante, te arriesgas a terminar con infinitas recursiones y, finalmente, la secuencia de comandos morirá debido a un stack overflow. No es raro documentar exactamente cuál es la variante en un comentario antes de las funciones recursivas.

+1

No. Use la orden interna array_walk_recursive(). PHP apesta en la recursión. –

0

Puede usar recursividad para este problema:

Aquí es un ejemplo

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

Se utilizará la recursividad para recorrer gama

se imprimirá como

a 
b 
c 
final value 
0

función simple en el interior array_walk_recursive para mostrar el nivel de anidación y las claves y valores:

array_walk_recursive($array, function($v, $k) { 
           static $l = 0; 
           echo "Level " . $l++ . ": $k => $v\n"; 
          }); 

Otra muestra use con una referencia para obtener un resultado:

array_walk_recursive($array, function($v) use(&$result) { 
           $result[] = $v; 
          }); 
Cuestiones relacionadas