2009-12-23 39 views
2

我有一个函数,它必须接受一个点数组或一个点数组(一个2或3维数组)的数组。我正在寻找一种可靠的方法来检测它是否有2或3级。关键是,我不能指望在阵列上的按键做检查,所以这不会工作:如何正确计算数组中的级别数量?

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

..as第一关键可能不是0它通常是,但我不我不想依赖这个。无论如何,这是一个蹩脚的和非常谨慎的方式来做到这一点。最好,我想检查任何数量的水平没有必须遍历整个阵列。

这里的阵列可能是什么样子:

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

和三维阵列将包含这些阵列。

一些注意事项:

  • 数组是很大,所以通过阵列完全循环是不是一个很好的选择
  • 的阵列数字和顺序索引(与最后一个级别的例外,已经x和y)
  • 数组键可能会或可能不会从0

在写这开始,我提出了这可能是可行的解决方案;一个递归函数,检查数组的第一项,如果是,则调用它自己的新发现数组等。

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

+0

我不认为有任何其他方式,因为PHP数组实际上是作为树实现的,而不是数组,所以它不知道数组中有多少“层”。 – 2009-12-23 07:53:39

回答

5

如果你期待一个完整的一个或多个阵列的一个完整的数组,那么你可以尝试: -

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

但是,如果你的数组稀疏,那么它更难。 基本的问题是,一个PHP“数组”实际上是一维散列。诀窍是一个值可以是另一个“数组”。所以你需要访问第二级来确定它是一个值还是一个数组。

再次,如果你期望一个给定的数组只包含点值,或者你只需​​要检查一个条目,只有其他阵列:

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

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

+0

当前(当前($分))解决方案适用于这种情况,所以我会使用它。至少它比我想象中的任何东西都干净,它也适用于具有未知开始键的阵列。谢谢! – 2009-12-23 08:59:55

1

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

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

/** 
* 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; 
     for ($array 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); 
+0

在PHP中没有这样的构造: ($ array as $ i){ 你测试了你的代码吗? – mrarm 2015-11-17 07:44:41

1

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