Проверка многомерности массива или нет?

  1. каков наиболее эффективный способ проверить, является ли массив плоский массив примитивных ценностей или многомерный массив?
  2. есть ли способ сделать это без зацикливания через массив и запуск is_array() по каждому из его элементов?

22 ответов


короткий ответ: Нет вы не можете сделать это без цикла по крайней мере неявно, если второе измерение может быть где угодно. Если это должно быть в первом элементе, вы просто сделаете

is_array($arr[0]);

но самый эффективный общий способ, который я мог бы найти, - использовать цикл foreach в массиве, замыкание всякий раз, когда найдено попадание (по крайней мере, неявный цикл лучше, чем прямой для()):

$ 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)

использовать 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:

Если необязательный параметр mode имеет значение COUNT_RECURSIVE (или 1), count () будет рекурсивно считать массив. Это особенно полезно для подсчета всех элементов многомерного массива. count () не обнаруживает бесконечную рекурсию.

однако этот метод не обнаруживает array(array()).


для PHP 4.2.0 или новее:

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

Вы можете просто выполнить это:

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

Если необязательный параметр Mode имеет значение COUNT_RECURSIVE (или 1), count () будет рекурсивно считать массив. Это особенно полезно для подсчета всех элементов многомерного массива.

Если это то же самое, означает, что нигде нет подуровней. Легко и быстро!


Я думаю, что это самый прямой путь, и это государство-оф-искусство:

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

вы можете посмотреть check is_array() на первом элементе, при условии, что если первый элемент массива является массивом, то все остальные тоже.


все великие ответы... вот мои три строки, которые я всегда использую

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

эта функция возвращает int количество измерений массива (украденных из здесь).

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

   return $return;
}

Я думаю, вы найдете, что эта функция является самым простым, эффективным и быстрым способом.

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

вы также можете сделать простую проверку как это:

$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

попробуйте сделать следующее

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

}else{

  echo 'arrayList is no multidimensional';
}

Я думаю, что это классный (реквизит для другого пользователя, я не знаю его имя пользователя):

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

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

все вышеперечисленные методы слишком сложны для быстрого развертывания. Если массив плоский, тестирование первого элемента должно возвращать примитив e.g int, строка e.т. c. Если он многомерен,он должен возвращать массив. По расширению, вы можете использовать этот один лайнер быстро и аккуратно.

echo is_array(array_shift($myArray));

если это возвращает true, массив является многомерным. Иначе она плоская. Просто отметим, что очень редко массивы имеют разные размеры, например, если вы генерируете данные из модели, это будет всегда имеют один и тот же тип многомерной или плоской структуры, которые могут быть пройдены петлями. machine made loops Если это не так, то вы создали его вручную, что означает, что вы знаете, где все будет, и он просто работает без необходимости писать алгоритм цикла enter image description here


В дополнение к предыдущим ответам и в зависимости от схемы массива, который вы хотите проверить:

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

даже это работает

is_array(current($array));

Если false его один размера массив if правда его multi dimension массив.

настоящее даст вам первый элемент вашего массива и проверьте, является ли первый элемент массивом или нет is_array


Не используйте 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 ) );

в моем случае. Я застрял в Варах странное состояние.
1-й случай = array("data"=> "name");
2-й случай = array("data"=> array("name"=>"username","fname"=>"fname"));
Но если ... --3--> имеет массив вместо значения, тогда функция sizeof() или count() не работает для этого условия. Затем я создаю пользовательскую функцию для проверки.
Если первый индекс массива имеет значение, то он возвращает "только значение"
Но если индекс имеет массив вместо значения, то он возвращает "имеет массив"
Я использую этот способ

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

особая благодарность Vrsalovic Винко


собственная функция print_r возвращает читаемую человеком строку. Просто подсчитайте экземпляры "Array".

попробовать...

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 занял 0.83681297302246 секунд в 500000 раз"

Любезность: РУАХ Хакодеш


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

if ( array_key_exists(0,$array) ) {

// multidimensional array

}  else {

// not a multidimensional array

}

*только для массивов с числовым индексом


function isMultiArray(array $value)
{
    return is_array(reset($value));
}

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

нет петель, просто и просто.

работает также с ассоциированными массивами не только числовыми массивами, которые не могут содержать 0 ( как в предыдущем примере, вы получите предупреждение, если массив не имеет 0. )