2011-09-28 40 views
9

Ai đó có thể giúp tôi với một số mã hoặc hướng dẫn về cách đi bộ đệ quy một mảng và khi đến phần tử cuối cùng in đường dẫn đầy đủ đến nó? Một tiếng vang đơn giản sẽ hoạt động vì tôi sẽ điều chỉnh mã cho một số chức năng khác mà tôi đang phát triển.Đi bộ mảng đệ quy và in đường đi bộ

Chức năng không cần phải tìm kích thước mảng vì param này sẽ được thông qua:

Ví dụ:

$depth = 8; 

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

Khi chức năng đạt từ yếu tố thứ 8 nó in tất cả các đường dẫn đến nó:

//print path 
'1 -> 3 -> 5 -> 6 -> 9 -> 5 -> 8 -> 9' 
  • Như tôi đã nói, chỉ in ở định dạng này sẽ làm việc vì tôi sẽ triển khai mã vào một số hàm khác.

  • các khóa mảng có thể có cùng giá trị. Rõ ràng không phải là cùng một giá trị trong cùng một chuỗi cho toàn bộ arary.

Cập nhật:

Walk đệ quy chức năng:

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

Sẽ in:

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

Bây giờ, làm thế nào tôi có thể cũng in các con đường của mảng mọi lúc nó đến cuối? Ví dụ:

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 MÃ BỔ SUNG MỘT PARAM BA để ghi lại các 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); 

Sẽ in:

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

Vâng, đó là nhiệm vụ cơ bản để giải quyết với đệ quy. Bạn đã thử cái gì? – zerkms

+0

@zerkms thực sự tôi có mã này cho đệ quy http://codepad.org/iyrcdfQP nhưng Im bị mắc kẹt trên một phần để theo dõi đường dẫn đến khóa $ hiện tại. – Henrique

+0

Bạn có thể đưa ra một ví dụ rõ ràng hơn, những gì của nhiều mục trong bất kỳ độ sâu nhất định của mảng hoặc nếu mảng không được lồng sâu sâu như '$ depth'? Vấn đề gì là giải quyết này? – salathe

Trả lời

14

Bạn có thể sử dụng RecursiveIteratorIterator (docs) để thực hiện công việc khó khăn trong việc đệ quy thông qua các mảng.

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

Điều này nghe có vẻ tốt hơn rất nhiều! Cảm ơn bạn rất nhiều!!! – Henrique

+0

điều này thật tuyệt vời! cám ơn! – claudioivp

+0

Tìm kiếm chính xác điều này, cảm ơn. –

0

Ví dụ này là để cho bạn ý tưởng, chứ không phải để giải quyết nhiệm vụ thực tế.

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

Nếu không tìm thấy kết quả phù hợp, trả về giá trị rỗng.

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

Bạn có thể thêm thông số thứ ba giữ đường dẫn thực tế dưới dạng Chuỗi. Cuối cùng, bạn có thể xuất nó.

+0

đã cố gắng nhưng không đơn giản như vậy. Kiểm tra mã tôi vừa chỉnh sửa. Lời khuyên nào? – Henrique

0

tôi chỉ viết một chức năng mà làm đệ quy looping một chút dễ dàng hơn: Tương tự như array_walk_recursive nhưng với một số chức năng phụ

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

gọi như vậy:

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

Thiết đệ quy để sai sẽ chỉ đánh giá mức đầu tiên.

Đặt đệ quy thành true sẽ khiến nó di chuyển toàn bộ mảng.

Đặt đệ quy thành số nguyên sẽ làm cho nó chỉ di chuyển đến độ sâu đó.

Chức năng có thể truy cập có thể được tham chiếu hoặc chuyển đến gọi lại dưới dạng hàm ẩn danh.

(dự kiến: giá trị, khóa, tùy chỉnh, thông tin) Giá trị trả lại thay thế giá trị hiện tại.

Dữ liệu tùy chỉnh có thể được chuyển và một số thông tin bổ sung được cung cấp cho bạn.

Bạn có thể mở rộng chức năng đi bộ nếu bạn cần thêm thông tin.

0

Tôi gặp sự cố tương tự. Đây là một giải pháp tìm kiếm-sâu thứ nhất-Dep (không có độ sâu đường dẫn đi kèm, nó đạt đến tận cùng của mảng). Bình luận 'if' tuyên bố nếu u không muốn bao gồm các giá trị:

$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

Các vấn đề liên quan