2011-09-28 57 views
9

有人可以帮助我一些代码或指导如何递归地走一个数组,并在到达最后一个元素时打印它的完整路径?一个简单的回声将起作用,因为我将使代码适应我正在开发的一些其他功能。递归地走数组并打印走的路径

该函数不需要计算阵列方向,因为这PARAM将被传递:

实施例:

$depth = 8; 

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

当功能reachs其打印到它所有的路径的第八元件:

//print path 
'1 -> 3 -> 5 -> 6 -> 9 -> 5 -> 8 -> 9' 
  • 正如我所说的,只有在这个幅面打印将工作的原因我会将代码实施到其他功能中。

  • 数组键可以具有相同的值。显然,在整个文学作品的同一个序列中价值不同。

更新时间:

步行递归函数:

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

会打印:

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

现在,我怎么也打印阵列的路径每次它到达最后?例如:

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 

编辑的代码添加第三个参数去记录路径:

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

会打印:

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, 
+0

嗯,这是基本任务与递归来解决。你有什么尝试? – zerkms

+0

@zerkms其实我有这个代码为递归http://codepad.org/iyrcdfQP但Im卡在零件跟踪到当前$键的路径。 – Henrique

+0

你可以给出一个更清晰的例子,在任何给定的数组深度内的多个项目,或者如果该数组嵌套深'深度'?这解决了什么问题? – salathe

回答

14

您可以使用RecursiveIteratorIteratordocs)来完成在数组中递归的辛苦工作。

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>"; 
     } 
    } 
} 
+0

听起来好多了!万分感谢!!! – Henrique

+0

这太神奇了!谢谢! – claudioivp

+0

寻找这个,谢谢。 –

0

这个例子是给你的想法,而不是解决实际任务。

function recursiveSearch($array,$search){ 
    foreach($array as $key=>$val){ 
     if($val==$search)return $key; 
     $x=recursiveSearch($array[$key],$search); 
     if($x)return $key.' -> '.$x; 
    } 
} 

echo recursiveSearch($array,'search'); 

如果找不到匹配项,则返回null。

0
$a= array(1,2,3,4,5,6); 
$val = end($a); 
print_array($a,$val); 
function print_array(&$arr, $val) 
{ 
    if ($val === false) 
     return; 

    $curr = prev($arr); 
    print_array($arr,$curr); 
    echo $val; 
} 
-1

您可以添加第三个参数,它将实际路径保存为字符串。最后你可以输出它。

+0

已经尝试过,但并不那么简单。检查我刚刚编辑的代码。有什么建议? – Henrique

0

我只是写了一个函数,使得递归循环更容易一点:类似 到array_walk_recursive但也有一些额外的功能

public static function walk($array, $callback, $custom = null, $recursive = false, $info = []) 
{ 
    $r = $recursive; 
    if (gettype($r) === 'integer') { 
     $r--; 
    } 
    $info['depth'] = empty($info)?1:$info['depth'] + 1; 
    $info['count'] = count($array); 
    $info['i'] = 1; 
    foreach($array as $k => $v) { 
     if (is_array($v) && $r > 0) { 
      $array[$k] = static::walk($v, $callback, $custom, $r, $info); 
     } else { 
      $array[$k] = $callback($v, $k, $custom, $info); 
     } 
     $info['i'] ++; 
    } 
    return $array; 
} 

public static function walkable($v, $k, $custom, $info) 
{ 
    if (is_string($v)) { 
     return $v." [ custom: {$custom['key']} ] [ level: ".$info['depth'].' | No '.$info['i'].' of '.$info['count']." ]"; 
    } 
    return $v; 
} 

调用,像这样:

$result = Namespace\ClassName::walk($array, ['Namespace\ClassName', 'walkable'], ['key'=>'value'], true); 

设置递归到假只会评估第一级。

将recursive设置为true会导致它遍历整个数组。

将递归设置为整数将使其仅遍历该深度。

可移动的函数可以作为匿名函数被引用或传递给回调函数。

(期望:值,键,自定义,信息) 返回值替换当前值。

自定义数据可以通过,并为您提供一些额外的信息。

如果您需要其他信息,您可以扩展漫游功能。

0

我有类似的问题。这是深度优先搜索解决方案(不包括路径深度,直到数组的最后)。注释“如果”语句如果你不希望包含的值:

$output = array(); 
retrievePath($someArray, $output); 

function retrievePath($someArray, array &$pathKeeper) 
{ 
    if(!is_array($someArray)){ // $someArray == "end" 
     $element = array_pop($pathKeeper) ?? '';// if the array is empty pop returns null, we don't want that 
     array_push($pathKeeper, $element . '->'. $someArray); 
    } else{ 
     end($someArray);//we want to get the last element from the array so we move the internal pointer to it's end 
     $endElKey = key($someArray);//take the key where the pointer is 
     reset($someArray); 
     foreach($someArray as $key=>$value){ 
      $element = array_pop($pathKeeper); 
      array_push($pathKeeper, $element === null ? $key : $element . '->' . $key);// we don't want '->' at the beginning 
      retrievePath($value, $pathKeeper); 
      if($key != $endElKey) //we check whether this is not the last loop 
       array_push($pathKeeper, $element); 
     } 
    } 
} 
0
<?php 
function printListRecursive($a, $var='', $i = 0) { 
    if (!is_array($a)) { 
     $var .= $a; 
     return $var; 
    } 
    $string = ""; 
    foreach ($a as $k => $value) { 
     $string .= str_repeat("&nbsp;&nbsp;", $i) .' - '. $k . ':'; 
     if (!is_array($value)) { 
      $string .= $value . '<br />'; 
     } else { 
      $string .= '<br />'; 
      $string .= printListRecursive($value, $var, $i + 1); 
     } 
    } 
    return $string; 
} 
$test_array = [ 
    'America' => [ 
     'Argentina' => 'Buenos Aires', 
     'Peru' => 'Lima' 
    ], 
    'Europe' => [ 
     'Ireland' => 'Dublin', 
     'France' => 'Paris', 
     'Italy' => 'Rome' 
    ] 
]; 
$result = printListRecursive($test_array); 
echo $result; 
?> 

Check code here