154
  1. 检查数组是原始值的平面数组还是多维数组的最有效方法是什么?
  2. 有没有办法做到这一点,而无需实际循环遍历数组并is_array()在其每个元素上运行?
4

25 回答 25

222

使用 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())

于 2009-06-15T05:33:45.783 回答
144

简短的回答是不,如果“第二维度”可以在任何地方,你至少不能隐式循环。如果它必须在第一个项目中,你就这样做

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)
于 2008-09-28T06:29:31.087 回答
30

对于 PHP 4.2.0 或更新版本:

function is_multi($array) {
    return (count($array) != count($array, 1));
}
于 2008-09-29T21:02:18.860 回答
14

我认为这是最直接的方式,也是最先进的:

function is_multidimensional(array $array) {
    return count($array) !== count($array, COUNT_RECURSIVE);
}
于 2016-05-10T18:16:29.323 回答
11

你可以简单地执行这个:

if (count($myarray) !== count($myarray, COUNT_RECURSIVE)) return true;
else return false;

如果可选的 mode 参数设置为COUNT_RECURSIVE(或 1),count() 将递归地对数组进行计数。这对于计算多维数组的所有元素特别有用。

如果相同,则意味着任何地方都没有子级别。简单快捷!

于 2014-03-22T17:28:42.370 回答
8

您可以检查is_array()第一个元素,假设如果数组的第一个元素是数组,那么其余元素也是。

于 2008-09-28T06:25:25.933 回答
8

在 PHP 7 之后,您可以简单地执行以下操作:

public function is_multi(array $array):bool
{
    return is_array($array[array_key_first($array)]);
}
于 2020-04-11T10:47:47.473 回答
4

所有很好的答案......这是我一直在使用的三行

function isMultiArray($a){
    foreach($a as $v) if(is_array($v)) return TRUE;
    return FALSE;
}
于 2013-07-26T02:22:15.703 回答
2

此函数将返回数组维度的 int 数(从此处窃取)。

function countdim($array)
{
   if (is_array(reset($array))) 
     $return = countdim(reset($array)) + 1;
   else
     $return = 1;

   return $return;
}
于 2008-09-28T06:26:18.100 回答
2

我想你会发现这个函数是最简单、最有效、最快的方法。

function 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';
于 2011-06-10T11:37:12.027 回答
2

即使这样也有效

is_array(current($array));

如果为,则为单维数组,如果为,则为多维数组。

current将为您提供数组的第一个元素,并通过is_array函数检查第一个元素是否为数组。

于 2017-04-13T13:17:26.997 回答
2

不要使用 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 ) );
于 2018-02-25T16:06:41.770 回答
1

你也可以像这样做一个简单的检查:

$array = array('yo'=>'dream', 'mydear'=> array('anotherYo'=>'dream'));
$array1 = array('yo'=>'dream', 'mydear'=> 'not_array');

function is_multi_dimensional($array){
    $flag = 0;
    while(list($k,$value)=each($array)){
        if(is_array($value))
            $flag = 1;
    }
    return $flag;
}
echo is_multi_dimensional($array); // returns 1
echo is_multi_dimensional($array1); // returns 0
于 2013-04-25T05:51:30.200 回答
1

尝试如下

if (count($arrayList) != count($arrayList, COUNT_RECURSIVE)) 
{
  echo 'arrayList is multidimensional';

}else{

  echo 'arrayList is no multidimensional';
}
于 2016-04-01T19:25:47.903 回答
1

就我而言。我陷入了各种奇怪的状态。
第一种情况 =array("data"=> "name");
第二种情况 =array("data"=> array("name"=>"username","fname"=>"fname"));
但是如果data有数组而不是值,则 sizeof() 或 count() 函数不适用于这种情况。然后我创建自定义函数来检查。
如果数组的第一个索引有值,那么它返回“唯一值”
但是如果索引有数组而不是值,那么它返回“有数组”
我用这种方式

 function is_multi($a) {
        foreach ($a as $v) {
          if (is_array($v)) 
          {
            return "has array";
            break;
          }
          break;
        }
        return 'only value';
    }

特别感谢Vinko Vrsalovic

于 2018-03-27T10:41:32.377 回答
0

我认为这个很优雅(对另一个我不知道他的用户名的用户的道具):

static public function isMulti($array)
{
    $result = array_unique(array_map("gettype",$array));

    return count($result) == 1 && array_shift($result) == "array";
}
于 2014-10-17T00:30:10.260 回答
0

以上所有方法都过于复杂,无法快速推出。如果数组是平面的,测试第一个元素应该返回一个原始元素,例如 int、string 等。如果它是多维的,它应该返回一个数组。通过扩展,您可以快速而整洁地使用这一衬里。

echo is_array(array_shift($myArray));

如果返回 true,则数组是多维的。否则它是平的。请注意,数组很少有不同的维度,例如,如果您从模型生成数据,它将始终具有可以被循环遍历的相同类型的多维或平面结构。 机器制造的循环 如果不是,那么您已经手动定制了它,这意味着您知道所有内容将在哪里并且它可以正常工作而无需编写循环算法 在此处输入图像描述

于 2015-09-04T10:17:11.660 回答
0

除了前面的答案之外,还取决于您要检查的数组的架构:

function is_multi_array($array=[],$mode='every_key'){

    $result = false;

    if(is_array($array)){

        if($mode=='first_key_only'){

            if(is_array(array_shift($array))){

                $result = true;
            }
        }
        elseif($mode=='every_key'){

            $result = true;

            foreach($array as $key => $value){

                if(!is_array($value)){

                    $result = false;
                    break;
                }
            }
        }
        elseif($mode=='at_least_one_key'){

            if(count($array)!==count($array, COUNT_RECURSIVE)){

                $result = true; 
            }
        }
    }

    return $result;
}
于 2016-04-01T19:19:48.463 回答
0

它很简单

$isMulti = !empty(array_filter($array, function($e) {
                    return is_array($e);
                }));
于 2019-01-28T13:27:23.990 回答
0
$is_multi_array = array_reduce(array_keys($arr), function ($carry, $key) use ($arr) { return $carry && is_array($arr[$key]); }, true);

这是一个很好的衬里。它遍历每个键以检查该键的值是否为数组。这将确保真实

于 2020-01-24T06:33:18.107 回答
-1
if($array[0]){
//enter your code 
}
于 2014-02-28T11:39:11.913 回答
-1
if ( array_key_exists(0,$array) ) {

// multidimensional array

}  else {

// not a multidimensional array

}

*仅适用于具有数字索引的数组

于 2015-03-25T17:09:36.710 回答
-2
function isMultiArray(array $value)
{
    return is_array(reset($value));
}
于 2010-12-01T18:09:21.097 回答
-2

本机 print_r 函数返回人类可读的字符串。只需计算“数组”实例。

尝试...

substr_count(print_r([...array...], true), 'Array') > 1;

$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)));
$d = array(array());
$e = array(1, array());
$f = array(array(), array());
$g = array("hello", "hi" => "hi there");
$h[] = $g;

var_dump(substr_count(print_r($a, true), 'Array') > 1);
...

//a: bool(true)
//b: bool(false)
//c: bool(true)
//d: bool(true)
//e: bool(true)
//f: bool(true)
//g: bool(false)
//h: bool(true)

在我的盒子上,“is_multi 在 500000 次中花费了 0.83681297302246 秒”

礼貌:Ruach HaKodesh

于 2018-10-05T16:27:09.207 回答
-3
is_array($arr[key($arr)]); 

没有循环,简单明了。

不仅可以与不能包含 0 的数字数组一起使用,还可以与关联数组一起使用(就像在前面的示例中一样,如果数组没有 0,则会向您发出警告。)

于 2010-06-11T14:25:59.813 回答