Существует ли способ узнать, как “глубоко” массив PHP?

Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  1. Вызов метода экземпляра объекта null.
  2. Доступ или изменение поля объекта null.
  3. Принимая длину null, как если бы это был массив.
  4. Доступ или изменение слотов null, как если бы это был массив.
  5. Бросок null как будто это было значение Throwable.

Приложения должны бросать экземпляры этого класса, чтобы указать на другие незаконные использования объекта null.

Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html

49
задан giannis christofakis 15 November 2013 в 01:23
поделиться

5 ответов

Это должно сделать это:

<?php

function array_depth(array $array) {
    $max_depth = 1;

    foreach ($array as $value) {
        if (is_array($value)) {
            $depth = array_depth($value) + 1;

            if ($depth > $max_depth) {
                $max_depth = $depth;
            }
        }
    }

    return $max_depth;
}

?>

Редактирование: Протестированный это очень быстро и это, кажется, работает.

61
ответ дан Kaii 7 November 2019 в 11:13
поделиться

Я не думаю, что существует что-либо, встроил. Простая рекурсивная функция могла легко узнать все же.

1
ответ дан KernelM 7 November 2019 в 11:13
поделиться

Остерегаются из примеров, которые просто делают это рекурсивно.

Php может создать массивы со ссылками на другие места в том массиве и может содержать объекты с аналогично рекурсивной ссылкой, и любой чисто рекурсивный алгоритм можно было рассмотреть в таком случае ОПАСНО наивный, в котором это переполнит рекурсивного вызова глубины стека, и никогда не завершаться.

(хорошо, это завершится, когда это превысит глубину стека, и в той точке, Ваша программа фатально завершит, не, что я думаю, что Вы хотите)

В прошлом, я попробовал, сериализируют-> заменяющий ссылочные маркеры строками->, десериализовывают для моих потребностей, (Часто отладка следов с загрузками рекурсивных ссылок в них), который, кажется, работает хорошо, Вы получаете дыры везде, но это работает на ту задачу.

Для Вашей задачи, если Вы находите, Ваш массив/структура имеет рекурсивные ссылки, неожиданно возникающие в нем, можно хотеть смотреть на внесенные комментарии пользователя здесь: http://php.net/manual/en/language.references.spot.php

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

Вы, возможно, должны вынуть свои книги CS по algorhthms и подбросить этих младенцев ударом:

(Извините за то, чтобы быть столь кратким, но копающийся в теории графов немного больше, чем удовлетворен для этого формата;))

43
ответ дан ComFreek 7 November 2019 в 11:13
поделиться

Вот другая альтернатива, которая избегает проблемы, на которую указал Kent Fredric. Это дает print_r () задача проверки бесконечную рекурсию (который это преуспевает), и использует добавление отступа в выводе для нахождения глубины массива.

function array_depth($array) {
    $max_indentation = 1;

    $array_str = print_r($array, true);
    $lines = explode("\n", $array_str);

    foreach ($lines as $line) {
        $indentation = (strlen($line) - strlen(ltrim($line))) / 4;

        if ($indentation > $max_indentation) {
            $max_indentation = $indentation;
        }
    }

    return ceil(($max_indentation - 1) / 2) + 1;
}
73
ответ дан Jeremy Ruten 7 November 2019 в 11:13
поделиться

Вот моя немного измененная версия функции Джереми Рутена

// you never know if a future version of PHP will have this in core
if (!function_exists('array_depth')) {
function array_depth($array) {
    // some functions that usually return an array occasionally return false
    if (!is_array($array)) {
        return 0;
    }

    $max_indentation = 1;
    // PHP_EOL in case we're running on Windows
    $lines = explode(PHP_EOL, print_r($array, true));

    foreach ($lines as $line) {
        $indentation = (strlen($line) - strlen(ltrim($line))) / 4;
        $max_indentation = max($max_indentation, $indentation);
    }
    return ceil(($max_indentation - 1) / 2) + 1;
}
}

Такие вещи, как print array_depth($GLOBALS) не вызовут ошибок из-за рекурсии, но вы можете не получить ожидаемого результата.

3
ответ дан 7 November 2019 в 11:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: