Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
345 views
in Technique[技术] by (71.8m points)

php - Walk array recursively and print the path of the walk

Can someone help me with some code or instructions on how to walk recursively an array and when reaching the last element print the full path to it? A simple echo will work because I will adapt the code to some other function I'm developing.

The function doesn't need to figure the array dimension because this param will be passed:

Example:

$depth = 8;

$array[1][3][5][6][9][5][8][9];

When function reachs the 8th element it print all the path to it:

//print path
'1 -> 3 -> 5 -> 6 -> 9 -> 5 -> 8 -> 9'
  • As I said, only printing in this format will work cause I will implement the code into some other function.

  • array keys can have the same value. Obviously not the same value in the same sequence for the entire arary.

Updated:

Walk recursively function:

$someArray[1][2][3] = 'end';
$someArray[1][2][6] = 'end';
$someArray[1][3][6] = 'end';
$someArray[4][3][7] = 'end';

function listArrayRecursive(&$array_name, $ident = 0){
    if (is_array($array_name)){
        foreach ($array_name as $k => &$v){
            if (is_array($v)){
                for ($i=0; $i < $ident * 10; $i++){ echo "&nbsp;"; }
                echo $k . " : " . "<br>";
                listArrayRecursive($v, $ident + 1);
            }else{
                for ($i=0; $i < $ident * 10; $i++){ echo "&nbsp;"; }
                echo $k . " : " . $v . "<br>";
            }
        }
    }else{
        echo "Variable = " . $array_name;
    }
}

listArrayRecursive($someArray);

Will print:

1 :
      2 :
                3 : end
                6 : end
      3 :
                6 : end
4 :
      3 :
                7 : end

Now, how can I also print the path of the array everytime it reaches the end? For example:

1 :
      2 :
                3 : end : path -> 1,2,3
                6 : end : path -> 1,2,6
      3 :
                6 : end : path -> 1,3,6
4 :
      3 :
                7 : end : path -> 4,3,7

EDITED CODE ADDING A THIRD PARAM TO RECORD THE PATH:

$someArray[1][2][3] = 'end';
$someArray[1][2][6] = 'end';
$someArray[1][3][6] = 'end';
$someArray[4][3][7] = 'end';
$someArray[3][2] = 'end';

function listArrayRecursive(&$array_name, $ident = 0, $path = null){
     foreach ($array_name as $k => &$v){
         if (is_array($v)){
            for ($i=0; $i < $ident * 10; $i++){ echo "&nbsp;"; }
            echo $k . " : " . "<br>";
            $path .= $k . ', ';
            listArrayRecursive($v, $ident + 1, $path);
        }else{
             for ($i=0; $i < $ident * 10; $i++){ echo "&nbsp;"; }
             echo $k . " : " . $v . ' - path -> ' . $path . "<br>";
        }
    }
}

listArrayRecursive($someArray);

Will print:

1 :
          2 :
                    3 : end - path -> 1, 2,
                    6 : end - path -> 1, 2,
          3 :
                    6 : end - path -> 1, 2, 3,
4 :
          3 :
                    7 : end - path -> 1, 4, 3,
3 :
          2 : end - path -> 1, 4, 3, 
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You could employ a RecursiveIteratorIterator (docs) to take the hard work out of recursing through the arrays.

function listArrayRecursive($someArray) {
    $iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($someArray), RecursiveIteratorIterator::SELF_FIRST);
    foreach ($iterator as $k => $v) {
        $indent = str_repeat('&nbsp;', 10 * $iterator->getDepth());
        // Not at end: show key only
        if ($iterator->hasChildren()) {
            echo "$indent$k :<br>";
        // At end: show key, value and path
        } else {
            for ($p = array(), $i = 0, $z = $iterator->getDepth(); $i <= $z; $i++) {
                $p[] = $iterator->getSubIterator($i)->key();
            }
            $path = implode(',', $p);
            echo "$indent$k : $v : path -> $path<br>";
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...