Может ли кто-нибудь помочь мне с некоторым кодом или инструкциями о том, как рекурсивно пройти по массиву и при достижении последнего элемента вывести полный путь к нему? Простое эхо будет работать, потому что я адаптирую код к какой-то другой разрабатываемой мной функции.
Функция не должна определять размер массива, потому что этот параметр будет передан:
Пример:
$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 " "; }
echo $k . " : " . "<br>";
listArrayRecursive($v, $ident + 1);
}else{
for ($i=0; $i < $ident * 10; $i++){ echo " "; }
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 " "; }
echo $k . " : " . "<br>";
$path .= $k . ', ';
listArrayRecursive($v, $ident + 1, $path);
}else{
for ($i=0; $i < $ident * 10; $i++){ echo " "; }
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,
Я нашел это решение, которое также сохраняет во внимание, если элементы структуры являются массивами:
$file_contents=file_get_contents("data.json");
$json_dump=json_decode($file_contents);
printPath($json_dump, '', "" ,"");
function printPath($the_array, $path, $prevType) {
// Parse all elements of a structure
// and print full PHP path to each one.
foreach($the_array as $key => $value) {
if(is_array($value)) {
// Array element cannot be directly printed: process its items as objects:
printPath($value, $path . $key , "array");
} else {
if (!is_object($value)) { // If the element is not an object, it can be printed (it's a leaf)
if(is_string($value)) {
$finalValue = '"' . $value . '"';
} else {
$finalValue = $value;
}
if($prevType == "array") {
// If array element, add index in square brackets
echo($path . "[" . $key . "] = " . $finalValue . "<br>");
} else {
echo($path . $key . " = " . $finalValue . "<br>");
}
} else { // else store partial path and iterate:
if($prevType == "array") {
// Path of array element must contain element index:
printPath($value, $path . "[" . $key . "]->" , "dummy");
} else {
printPath($value, $path . $key . "->", "dummy");
}
}
}
}
}
Пример произвел:
status->connections->DSS-25->band = "X"
status->connections->DSS-25->endAt = "2019-11-20T20:40:00.000Z"
status->connections->DSS-25->startAt = "2019-11-20T12:40:00.000Z"
geometry[0]->obs[0]->name = "UDSC64"
geometry[0]->obs[0]->hayabusa2->azm = 90.34
geometry[0]->obs[0]->hayabusa2->alt = -20.51
В случае, если кому-либо интересно, здесь это - порт к JavaScript:
function iterate(obj, stack, prevType) {
for (var property in obj) {
if ( Array.isArray(obj[property]) ) {
//console.log(property , "(L=" + obj[property].length + ") is an array with parent ", prevType, stack);
iterate(obj[property], stack + property , "array");
} else {
if ((typeof obj[property] != "string") && (typeof obj[property] != "number")) {
if(prevType == "array") {
//console.log(stack + "[" + property + "] is an object, item of " , prevType, stack);
iterate(obj[property], stack + "[" +property + "]." , "object");
} else {
//console.log(stack + property , "is " , typeof obj[property] , " with parent ", prevType, stack );
iterate(obj[property], stack + property + ".", "object");
}
} else {
if(prevType == "array") {
console.log(stack + "[" + property + "] = "+ obj[property]);
} else {
console.log(stack + property , " = " , obj[property] );
}
}
}
}
}
iterate(object, '', "File")