【问题标题】:Checking if array is multidimensional or not?检查数组是否是多维的?
【发布时间】:2010-09-13 19:20:27
【问题描述】:
  1. 检查数组是否是平面数组的最有效方法是什么 原始值还是多维数组
  2. 有什么方法可以做到这一点,而无需实际循环 数组并在其每个元素上运行is_array()

【问题讨论】:

  • 值得指出的是,PHP 没有真正的多维数组——只是简单的值关联数组。所以你的问题真的是问“我的数组中是否有非标量值”?
  • 其实……我认为这根本不值得指出。

标签: php arrays loops multidimensional-array element


【解决方案1】:

使用 count() 两次;一次在默认模式下,一次在递归模式下。如果值匹配,则数组不是多维的,因为多维数组将具有更高的递归计数。

if (count($array) == count($array, COUNT_RECURSIVE)) 
{
  echo 'array is not multidimensional';
}
else
{
  echo 'array is multidimensional';
}

此选项第二个值mode 是在 PHP 4.2.0 中添加的。来自PHP Docs

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

但是此方法无法检测到array(array())

【讨论】:

  • 如前所述,这不适用于具有空数组的元素
【解决方案2】:

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

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)

【讨论】:

  • 很好,但需要注意的是,我认为您的过滤行应该有 array_map("is_array",$a),而不是使用 is_array 作为裸词。
  • 不错,加快了 is_multi,但仍不足以匹配 foreach
  • 值得注意的是,正如所写,multi_3 仅适用于从零开始且索引中没有间隙的非关联数组,这意味着它不会正确地将这些示例中的任何一个识别为多维度。
  • 在函数is_multi()中通过return count($rv)&gt;0优化代码
  • is_array(array_values($arr)[0]) 作为自定义键的解决方法。
【解决方案3】:

对于 PHP 4.2.0 或更新版本:

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

【讨论】:

  • 不适用于array(array())array(array(), array())。通常,如果内部数组为空,则递归计数将正确地为其添加 0,从而使其与正常计数匹配。
【解决方案4】:

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

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

【讨论】:

    【解决方案5】:

    你可以简单地执行这个:

    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))
    • 酷。 COUNT_RECURSIVE 或 1 与 count() 相同
    • 当然。我只是喜欢不那么杂乱,!== 用于查看是否存在子级别。对于可能正在寻找类似东西的理论......等等。
    • 你所拥有的对我来说并没有返回真实......我需要添加!==
    • 使用空数组,失败
    【解决方案6】:

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

    【讨论】:

    • 这实际上是一个好点。在我的特定情况下,这是一种非此即彼的情况,因为我正在控制原始数组的创建。我将暂时保留这个问题,以防有可能更普遍的解决方案。
    • 像这样:if( is_array(current($arr)) ) { // is multidimensional }
    【解决方案7】:

    在 PHP 7 之后,您可以简单地这样做:

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

    【讨论】:

      【解决方案8】:

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

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

      【讨论】:

        【解决方案9】:

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

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

        【讨论】:

        • 这仅适用于 Greg 的情况。这不是解决第二维可能位于数组中任何位置的问题的通用解决方案
        • $arr = array("hello", "hi" => "hi there"); $arr[] = &arr; //哎呀
        【解决方案10】:

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

        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;
        【解决方案11】:

        即使这样也有效

        is_array(current($array));
        

        如果false单维数组如果true多维数组。

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

        【讨论】:

        • 如果您想确保任何其他元素也不嵌套,那将是不可靠的。
        【解决方案12】:

        不要使用 COUNT_RECURSIVE

        click this site for know why

        使用 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] 可以是数组
        【解决方案13】:

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

        $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
        

        【讨论】:

          【解决方案14】:

          如下尝试

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

          【讨论】:

            【解决方案15】:

            就我而言。我陷入了各种奇怪的状况。
            第一种情况 = array("data"=&gt; "name");
            第二种情况 = array("data"=&gt; array("name"=&gt;"username","fname"=&gt;"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

            【讨论】:

              【解决方案16】:

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

              static public function isMulti($array)
              {
                  $result = array_unique(array_map("gettype",$array));
              
                  return count($result) == 1 && array_shift($result) == "array";
              }
              

              【讨论】:

                【解决方案17】:

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

                echo is_array(array_shift($myArray));
                

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

                【讨论】:

                • 此技术仅在第一个元素是数组时才找到多维数组。
                • 谨慎使用array_shift(),因为它会删除第一个元素并重置数字键!如果仍然渴望单线,最好使用current()
                【解决方案18】:

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

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

                【讨论】:

                  【解决方案19】:

                  就这么简单

                  $isMulti = !empty(array_filter($array, function($e) {
                                      return is_array($e);
                                  }));
                  

                  【讨论】:

                    【解决方案20】:
                    $is_multi_array = array_reduce(array_keys($arr), function ($carry, $key) use ($arr) { return $carry && is_array($arr[$key]); }, true);
                    

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

                    【讨论】:

                      【解决方案21】:
                      if($array[0]){
                      //enter your code 
                      }
                      

                      【讨论】:

                      • 至少使用if (isset($array[0])) { }。如果您确定数组的索引从 0 开始
                      • 多维数组是包含一个或多个数组的数组。这只检查它是否包含一个键为零的元素。
                      【解决方案22】:
                      if ( array_key_exists(0,$array) ) {
                      
                      // multidimensional array
                      
                      }  else {
                      
                      // not a multidimensional array
                      
                      }
                      

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

                      【讨论】:

                      • 多维数组是包含一个或多个数组的数组。这只检查它是否包含一个键为零的元素。
                      【解决方案23】:
                      function isMultiArray(array $value)
                      {
                          return is_array(reset($value));
                      }
                      

                      【讨论】:

                      • 这仅测试第一个元素是否是多维的。
                      【解决方案24】:

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

                      【讨论】:

                        【解决方案25】:
                        is_array($arr[key($arr)]); 
                        

                        没有循环,简单明了。

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

                        【讨论】:

                        • 在key上检测不到数组,需要检查值
                        猜你喜欢
                        • 2010-09-26
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2015-09-15
                        • 2013-07-07
                        • 1970-01-01
                        • 2018-06-01
                        • 2014-08-28
                        相关资源
                        最近更新 更多