Проведите массив рекурсивно и напечатайте путь ходьбы

Может ли кто-нибудь помочь мне с некоторым кодом или инструкциями о том, как пройти рекурсивно массив и при достижении последнего элемента распечатать полный путь к нему? Простое эхо будет работать, потому что я буду адаптировать код к некоторой другой функции, которую я разрабатываю.

Функция не должна указывать размерность массива, потому что этот параметр будет передан:

Пример:

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

Когда функция достигает 8-го элемента, он печатает весь путь к ней:

 //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 

EDITED CODE, ДОБАВЛЯЮЩИЙ ТРЕТИЙ ПАРАМ ДЛЯ ЗАПИСИ ПУТЬ:

 $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, 

Вы можете использовать RecursiveIteratorIterator ( docs ), чтобы выполнить сложную работу по рекурсии через массивы.

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

Этот пример – дать вам идею, а не решать настоящую задачу.

 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.

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

Я просто написал функцию, которая делает рекурсивный цикл немного проще: подобно 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); 

Установка рекурсивного значения на false будет оценивать только первый уровень.

Установка рекурсивного значения в true приведет к обходу всего массива.

Установка рекурсивного значения в целое число приведет к тому, что он будет переходить только на эту глубину.

Доступные функции могут ссылаться или передаваться на обратный вызов как анонимная функция.

(ожидается: значение, ключ, обычай, информация) Возвращаемое значение заменяет текущее значение.

Пользовательские данные могут быть переданы, а дополнительная информация предоставлена ​​вам.

Вы можете расширить функцию ходьбы, если вам нужна дополнительная информация.

У меня была схожая проблема. Здесь находится решение «Глубино-первое поиск» (без глубины пути, оно доходит до самого конца массива). Прокомментируйте инструкцию if, если вы не хотите включать значение:

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

Проверить код здесь

Вы можете добавить третий параметр, который содержит фактический путь как String. В конце вы можете его вывести.