Checking if array is multidimensional or not?

后端 未结 25 3210
醉话见心
醉话见心 2020-11-28 01:41
  1. What is the most efficient way to check if an array is a flat array of primitive values or if it is a multidimensional array?
相关标签:
25条回答
  • 2020-11-28 02:35
    if ( array_key_exists(0,$array) ) {
    
    // multidimensional array
    
    }  else {
    
    // not a multidimensional array
    
    }
    

    *only to those arrays with numeric index

    0 讨论(0)
  • 2020-11-28 02:36

    You can simply execute this:

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

    If the optional mode parameter is set to COUNT_RECURSIVE (or 1), count() will recursively count the array. This is particularly useful for counting all the elements of a multidimensional array.

    If it's the same, means there are no sublevels anywhere. Easy and fast!

    0 讨论(0)
  • 2020-11-28 02:36

    Don't use COUNT_RECURSIVE

    click this site for know why

    use rsort and then use isset

    function is_multi_array( $arr ) {
    rsort( $arr );
    return isset( $arr[0] ) && is_array( $arr[0] );
    }
    //Usage
    var_dump( is_multi_array( $some_array ) );
    
    0 讨论(0)
  • 2020-11-28 02:41

    Use count() twice; one time in default mode and one time in recursive mode. If the values match, the array is not multidimensional, as a multidimensional array would have a higher recursive count.

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

    This option second value mode was added in PHP 4.2.0. From the PHP Docs:

    If the optional mode parameter is set to COUNT_RECURSIVE (or 1), count() will recursively count the array. This is particularly useful for counting all the elements of a multidimensional array. count() does not detect infinite recursion.

    However this method does not detect array(array()).

    0 讨论(0)
  • 2020-11-28 02:42

    In addition to the previous answers and depending on the schema of the array you want to check:

    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 讨论(0)
  • 2020-11-28 02:43

    The short answer is no you can't do it without at least looping implicitly if the 'second dimension' could be anywhere. If it has to be in the first item, you'd just do

    is_array($arr[0]);
    

    But, the most efficient general way I could find is to use a foreach loop on the array, shortcircuiting whenever a hit is found (at least the implicit loop is better than the straight 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
    

    Implicit looping, but we can't shortcircuit as soon as a match is found...

    $ 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)
    
    0 讨论(0)
提交回复
热议问题