代码之家  ›  专栏  ›  技术社区  ›  Bryan Downing

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

  •  8
  • Bryan Downing  · 技术社区  · 16 年前

    我想知道数组在构建时的级别。

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

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

    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 回复  |  直到 16 年前
        1
  •  3
  •   Basic    16 年前

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

        2
  •  5
  •   salathe    16 年前

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

    $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, "/"));
    }
    

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

    DR 我们可以使用 SPL iterators 使使用递归/深层结构更加简单。

    TR;DR;TL;DR 哈哈,是啊!

        3
  •  3
  •   Sarfraz    16 年前

    应该这样做:

    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;
    }
    
        4
  •  0
  •   bobrik    16 年前
    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";
    
        5
  •  0
  •   NikiC    16 年前

    也许你问错了问题。最终目标是什么?例如,有一个 RecursiveDirectoryIterator 在SPL里上课,也许对你有用?构建一个大的多维数组会消耗大量的内存,所以简单地递归地遍历所有这些文件就足够了吗?