- 如何高效地检测一个数组是由基本类型值组成的一维数组还是多维数组?
- 是否有办法在不对数组进行循环并在每个元素上运行
is_array()
的情况下完成此操作?
is_array()
的情况下完成此操作?使用count()函数两次,一次在默认模式下,一次在递归模式下。如果两个值相等,则该数组不是多维数组,因为多维数组的递归计数会更高。
if (count($array) == count($array, COUNT_RECURSIVE))
{
echo 'array is not multidimensional';
}
else
{
echo 'array is multidimensional';
}
这个选项的第二个值 mode
在PHP 4.2.0中添加。来自PHP文档:
如果可选模式参数设置为COUNT_RECURSIVE(或1),则count()将递归计算数组。这对于计算多维数组的所有元素特别有用。 count()无法检测到无限递归。
然而,此方法无法检测到 array(array())
。
is_array($arr[0]);
然而,我找到的最有效的一般方法是在数组上使用foreach循环,在找到匹配项时进行短路(至少隐式循环比直接使用for()更好):
$ more multi.php
<?php
$a = array(1 => 'a',2 => 'b',3 => array(1,2,3));
$b = array(1 => 'a',2 => 'b');
$c = array(1 => 'a',2 => 'b','foo' => array(1,array(2)));
function is_multi($a) {
$rv = array_filter($a,'is_array');
if(count($rv)>0) return true;
return false;
}
function is_multi2($a) {
foreach ($a as $v) {
if (is_array($v)) return true;
}
return false;
}
function is_multi3($a) {
$c = count($a);
for ($i=0;$i<$c;$i++) {
if (is_array($a[$i])) return true;
}
return false;
}
$iters = 500000;
$time = microtime(true);
for ($i = 0; $i < $iters; $i++) {
is_multi($a);
is_multi($b);
is_multi($c);
}
$end = microtime(true);
echo "is_multi took ".($end-$time)." seconds in $iters times\n";
$time = microtime(true);
for ($i = 0; $i < $iters; $i++) {
is_multi2($a);
is_multi2($b);
is_multi2($c);
}
$end = microtime(true);
echo "is_multi2 took ".($end-$time)." seconds in $iters times\n";
$time = microtime(true);
for ($i = 0; $i < $iters; $i++) {
is_multi3($a);
is_multi3($b);
is_multi3($c);
}
$end = microtime(true);
echo "is_multi3 took ".($end-$time)." seconds in $iters times\n";
?>
$ php multi.php
is_multi took 7.53565130424 seconds in 500000 times
is_multi2 took 4.56964588165 seconds in 500000 times
is_multi3 took 9.01706600189 seconds in 500000 times
隐式循环,但是我们不能在找到匹配项后立即进行短路处理...
$ more multi.php
<?php
$a = array(1 => 'a',2 => 'b',3 => array(1,2,3));
$b = array(1 => 'a',2 => 'b');
function is_multi($a) {
$rv = array_filter($a,'is_array');
if(count($rv)>0) return true;
return false;
}
var_dump(is_multi($a));
var_dump(is_multi($b));
?>
$ php multi.php
bool(true)
bool(false)
is_multi()
中,通过执行 return count($rv)>0
来优化代码。 - Xorifelse对于 PHP 4.2.0 或更新版本:
function is_multi($array) {
return (count($array) != count($array, 1));
}
array(array())
或 array(array(), array())
也不起作用。通常,如果内部数组为空,则递归计数将正确地为其添加0,从而使其与正常计数匹配。 - Fanis Hatzidakis我认为这是最直接的方式,而且它还是最先进的:
function is_multidimensional(array $array) {
return count($array) !== count($array, COUNT_RECURSIVE);
}
在 PHP 7 之后,您可以简单地执行以下操作:
public function is_multi(array $array):bool
{
return is_array($array[array_key_first($array)]);
}
$array = ['0' => 0, '1' => ['0' => 1]];
这是一个多维数组,但你的函数返回 false。 - aProggeris_array()
函数进行检查,假设如果数组的第一个元素是一个数组,那么其余的元素也是数组。if( is_array(current($arr)) ) { // 是多维数组 }
- Jonas Äppelgranfunction isMultiArray($a){
foreach($a as $v) if(is_array($v)) return TRUE;
return FALSE;
}
$a = array(1 => 'a',2 => 'b',3 => array(1,2,3));
$b = array(1 => 'a',2 => 'b');
echo isMultiArray($a) ? 'is multi':'is not multi';
echo '<br />';
echo isMultiArray($b) ? 'is multi':'is not multi';
foreach($a as $v) is_array($v) ? return TRUE : return FALSE;
- Robert Pounderforeach($a as $v) return is_array($v) ? true : false;
- Yassine Sedrani不要使用COUNT_RECURSIVE
使用rsort,然后使用isset
function is_multi_array( $arr ) {
rsort( $arr );
return isset( $arr[0] ) && is_array( $arr[0] );
}
//Usage
var_dump( is_multi_array( $some_array ) );
is_array(current($array));
我认为这个很棒(向另一个用户致敬,我不知道他的用户名):
static public function isMulti($array)
{
$result = array_unique(array_map("gettype",$array));
return count($result) == 1 && array_shift($result) == "array";
}
array_map()
不允许短路,因此将遍历整个数组。此页面上有其他比这更好的解决方案。 - mickmackusa