检查数组是否为多维?


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

9
值得指出的是,PHP没有真正的多维数组,只有简单的关联数组值。因此,您的问题确实是在问“我的数组中是否存在非标量值”?
gahooa

21
其实...我认为一点都不值得指出。

Answers:


135

简短的答案是,如果“第二维”可能在任何地方,您都必须至少隐式​​循环才能做到。如果必须在第一项中,您只需

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)

3
很好,但请注意,我相信您的过滤行应具有array_map(“ is_array”,$ a),而不是将is_array用作裸字。
马修·沙利

好的接球,加快了is_multi的速度,但仍然不足以匹配foreach
Vinko Vrsalovic

2
值得注意的是,按照书面形式,multi_3将仅在基于零的非关联数组上工作,且索引之间没有间隙,这意味着它将无法正确地将这些示例识别为多维。
Cragmonkey '16

在函数中is_multi(),通过执行以下操作优化代码return count($rv)>0
Xorifelse

is_array(array_values($ arr)[0])作为自定义键的解决方法。
维托·罗德里格斯

191

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


2
如前所述,这不适用于具有空数组的元素
Arthur

30

对于PHP 4.2.0或更高版本:

function is_multi($array) {
    return (count($array) != count($array, 1));
}

不工作array(array())array(array(), array())两者兼而有之。通常,如果内部数组为空,则递归计数将为其正确添加0,从而使其与常规计数匹配。
法尼斯·哈齐达基斯

13

我认为这是最直接的方法,并且是最新技术:

function is_multidimensional(array $array) {
    return count($array) !== count($array, COUNT_RECURSIVE);
}

9

您可以简单地执行以下操作:

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

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

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


谢谢...有帮助。我想检查数组的子级别是否存在,我用过if(count($tasks_by_date) !== count($tasks_by_date, 1))
Mike Barwick

凉。count()的COUNT_RECURSIVE或1相同
Pian0_M4n 2015年

绝对。我只是喜欢减少混乱,并且!==过去经常看到次级别的存在。对于可能正在寻找类似...的理论
Mike Barwick

您所拥有的对我来说还不是真的...我需要加上!==
Mike Barwick

随着空数组,已失败
华莱士Maxters

7

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


这实际上是一个好点。在我的特定情况下,由于我控制原始数组的创建,因此是一种“或”的情况。我暂时不提问题,以防万一有可能更通用的解决方案。
Wilco

5
像这样:if( is_array(current($arr)) ) { // is multidimensional }
乔纳斯·阿佩格兰(JonasÄppelgran)2014年

4

所有不错的答案...这是我一直在使用的三行代码

function isMultiArray($a){
    foreach($a as $v) if(is_array($v)) return TRUE;
    return FALSE;
}

2

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

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

   return $return;
}

这仅适用于格雷格的情况。这不是解决第二维可以在数组中任何位置的问题的一般解决方案
Vinko Vrsalovic

$ arr = array(“ hello”,“ hi” =>“ hi there”); $ arr [] =&arr; // oops
Tyzoid

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';

如果您要单行处理,那么至少要完成整个操作;foreach($a as $v) is_array($v) ? return TRUE : return FALSE;
罗伯特·庞德

@RobertPounder甚至foreach($a as $v) return is_array($v) ? true : false;
亚辛Sedrani

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

1

尝试如下

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

}else{

  echo 'arrayList is no multidimensional';
}

1

即使这样有效

is_array(current($array));

如果了一个一维数组,如果属实的一个多维度阵列。

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


如果您要确保任何其他元素都不嵌套,那将是不可靠的。
vanamerongen

1

不要使用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 ) );

$ arr [0]不能是数组,但是$ arr [1]可以是数组
Supun Praneeth 18/11/27

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


1

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

public function is_multi(array $array):bool
{
    return is_array($array[array_key_first($array)]);
}

0

我认为这是一流的(针对另一个我不知道其用户名的用户):

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

    return count($result) == 1 && array_shift($result) == "array";
}

0

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

echo is_array(array_shift($myArray));

如果返回true,则表示数组是多维的。否则它是平坦的。请注意,数组具有不同维度的情况非常少见,例如,如果您从模型生成数据,则数组将始终具有相同类型的多维或平面结构,可以通过循环遍历。 机器制作的循环 如果不是,那么您需要手工定制构建它,这意味着您知道一切都在哪里,并且无需编写循环算法就可以正常工作。 在此处输入图片说明


如果第一个元素是数组,则此技术仅查找多维数组。
Cragmonkey '16

请谨慎使用array_shift(),因为它会删除第一个元素,并且还会重置数字键!最好current()还是使用单线止痒。
MarcelloMönkemeyer17年

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;
}


0
$is_multi_array = array_reduce(array_keys($arr), function ($carry, $key) use ($arr) { return $carry && is_array($arr[$key]); }, true);

这是一个不错的班轮。遍历每个键,以检查该键上的值是否为数组。这将确保真实


-1
if($array[0]){
//enter your code 
}

至少使用if (isset($array[0])) { }。如果您确定数组的索引从0开始
Aistis 2014年

多维数组是包含一个或多个数组的数组。这仅检查是否包含键为零的元素。
Cragmonkey '16

-1
if ( array_key_exists(0,$array) ) {

// multidimensional array

}  else {

// not a multidimensional array

}

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


多维数组是包含一个或多个数组的数组。这仅检查是否包含键为零的元素。
Cragmonkey '16

-1

本机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



-3
is_array($arr[key($arr)]); 

没有循环,简单明了。

不仅可以使用不能包含0的数字数组,还可以与关联数组一起使用(就像上一个示例中的警告一样,如果数组不包含0。)


无法在键上检测到数组,您必须检查该值
RoboTamer 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.