是否可以计算数组中的维数?

时间:2010-08-26 19:10:28

标签: php arrays multidimensional-array

我希望能够知道正在构建的数组的级别。

代码循环通过一堆目录来创建一个大规模的多维数组。

在创建数组时,我想知道数组的深度。

1    2    3    4
---------------------
Root
     A
          A2
          A3
          A4
               A4a
     B
          B2
          B3
     C
     D
     E
          E2
               E2a
          E3

在上面的例子中,根目录在1级。所有单个大写字母都在2级。所有带有数字的大写字母都在3级。所有带有数字和小写字母的大写字母都在4级

当我正在构建数组时,有什么方法让我知道我在哪个级别?正在使用递归函数创建数组。

这是一个PHP问题。

5 个答案:

答案 0 :(得分:5)

这可能与你关于数组的问题相关,但你可以通过使用递归目录迭代器一举两得。

$path_to_root = __DIR__;
$directories  = new ParentIterator(new RecursiveDirectoryIterator($path_to_root, RecursiveDirectoryIterator::CURRENT_AS_SELF));
$iterator     = new RecursiveIteratorIterator($directories, RecursiveIteratorIterator::SELF_FIRST);

foreach ($iterator as $item)
{
    printf("%d %s\n", $iterator->getDepth() + 1, $item->getSubPathname());
}

会输出类似的内容:

1 Root
2 Root/A
3 Root/A/A2
3 Root/A/A3
3 Root/A/A4
4 Root/A/A4/A4a
2 Root/B
3 Root/B/B2
3 Root/B/B3
2 Root/C
2 Root/D
2 Root/E
3 Root/E/E2
4 Root/E/E2/E2a
3 Root/E/E3

正如您所看到的,RecursiveIteratorIterator::getDepth()用于获取递归迭代器的当前深度,这是建议此方法的原因。


替代方案(如果必须使用数组)

假设您的数组结构类似于:

$dirs = array(
    'Root' => array(
        'A' => array(
            'A2' => array(),
            'A3' => array(),
            'A4' => array(
                'A4a' => array(),
            ),
        ),
        'B' => array(
            'B2' => array(),
            'B3' => array(),
        ),
        'C' => array(),
        'D' => array(),
        'E' => array(
            'E2' => array(
                'E2a' => array(),
            ),
            'E3' => array(),
        ),
    ),
);

然后可以使用非常相似的方法从递归目录迭代器获取值(但这次使用递归数组迭代器)。快速循环“父”数组可以为我们提供从当前项回到根的“路径”。

$recursive = new ParentIterator(new RecursiveArrayiterator($dirs));
$iterator  = new RecursiveIteratorIterator($recursive, RecursiveIteratorIterator::SELF_FIRST);

foreach ($iterator as $item)
{
    // Build path from "parent" array keys
    for ($path = "", $i = 0; $i <= $iterator->getDepth(); $i++) {
        $path .= "/" . $iterator->getSubIterator($i)->key();
    }
    // Output depth and "path"
    printf("%d %s\n", $iterator->getDepth() + 1, ltrim($path, "/"));
}

输出与目录迭代器的输出相同。

TL; DR 我们可以使用SPL iterators中的递归迭代器来更简单地处理递归/深层结构。

TL; DR; TL; DR SPL,哎呀!

答案 1 :(得分:3)

一个简单的答案就是简单地向函数添加“深度”参数,并在函数调用时递增它。

答案 2 :(得分:3)

这应该做:

function array_depth($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;
}

答案 3 :(得分:0)

function calc_dimensions(array $array) {
    $dimensions = 1;
    $max = 0;
    foreach ($array as $value) {
        if (is_array($value)) {
            $subDimensions = calc_dimensions($value);
            if ($subDimensions > $max) {
                $max = $subDimensions;
            }
        }
    }

    return $dimensions+$max;
}

$array = array(
    array(
        array(
            4 => 5,
            array(
                6 => 6
            )
        )
    ),
    1 => 5
);

echo calc_dimensions($array)."\n";

答案 4 :(得分:0)

也许你问的是错误的问题。最终目标是什么?例如,SPL中有一个RecursiveDirectoryIterator类,也许会为你做什么?构建一个大的多维数组会占用大量的内存,所以简单地迭代遍历所有这些文件就足够了吗?