如何正确计算数组中的级别数量?

时间:2009-12-23 07:43:18

标签: php arrays nested

我有一个函数必须接受一个点数组,或一组点数组(一个二维或三维数组)。我正在寻找一种可靠的方法来检测它是否有2级或3级。问题是,我不能指望数组的键来进行检查,因此不会工作:

$levels = isset($array[0][0]) && is_array($array[0][0]) ? 3 : 2;

..因为第一个键可能不是0.通常是,但我不想依赖于此。无论如何,这是一个糟糕而且很有思想的方式。最理想的情况是,我想检查没有必须遍历整个数组的任意级别。

以下是数组的外观:

array(5) {
    [2] => array(2) {
        [x] => 3
        [y] => 6
    }
    [3] => array(2) {
        [x] => 4
        [y] => 8
    }
    ...

三维数组将包含这些数组。

一些注意事项:

  • 数组很大,所以完全循环遍历数组不是一个很好的选择
  • 数组按数字顺序编制索引(除了最后一级,有x和y)
  • 数组键可能是也可能不是从0
  • 开始

在写这篇文章时,我想出了一个可行的解决方案;一个递归函数,它检查数组的第一项,如果是,则在新发现的数组上调用它自己。

有没有更好,更清洁的想法?支持可能同时具有标量值和数组的数组的加分点(例如,数组的第一项可能是字符串,但下一个是数组)。

3 个答案:

答案 0 :(得分:5)

如果您需要完整的数组或完整的数组,那么您可以尝试: -

if (isset $points[0][0][0])

但是,如果您的阵列稀疏则更难。 基本问题是php“数组”实际上是一维哈希。诀窍是值可以是另一个“数组”。因此,您需要访问第二级以确定它是值还是数组。

再次,如果您希望给定的数组只包含点值,或者只包含其他数组,那么您只需要检查一个条目:

if ( is_array(current(current($points))) )

应该得到你想要的东西: current()函数返回当前数组指针(默认为第一个 - 所以它总是被设置为某个东西),所以内部电流($会得到$ points [0]或第一个带有实际值的条目,外面的电流会得到类似$ points [0] [0]的东西。

答案 1 :(得分:2)

我没有看到你如何在没有至少迭代数组的情况下做到这一点。简单的事实是,数组中的任何一个元素都可以有一个额外的级别。因此,每个元素都需要进行测试。

话虽这么说,你仍然可以使用递归来改进你的代码:

/** 
 * Determine the maximum depth of an array.
 * @param $input The object to test. Might be an array, or might be an int (or
 *        any other object).
 * @param $startDepth The starting depth. Will be added as an offset to the
 *        result.
 * @return The depth of the array, plus any initial offset specified in
 *         $startDepth.
 */
function testDepth($input, $startDepth = 0) {
    if (is_array($input)) {
        $max = $startDepth;
        foreach ($input as $i) {
            // Check what the depth of the given element is
            $result = testDepth($i, $startDepth + 1);
            // We only care about the maximum value
            if ($result > $max) {
                $max = $result;
            }
        }
        return $max;
    } else {
        // This isn't an array, so it's assumed not to be a container.
        // This doesn't add any depth to the parent array, so just return $startDepth
        return $startDepth;
    }
}

testDepth($array);

答案 2 :(得分:1)

$ levels = is_array(当前(当前($ array)))? 3:2;