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


  1. Каков наиболее эффективный способ проверить, является ли массив плоским массивом примитивных значений или это многомерный массив ?
  2. Есть ли какой-либо способ сделать это без фактического перебора массива и запуска is_array() на каждом из его элементов?
Author: Josua Marcel Chrisano, 2008-09-28

22 answers

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

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)
 117
Author: Vinko Vrsalovic, 2008-09-28 07:15:27

Используйте count() дважды; один раз в режиме по умолчанию и один раз в рекурсивном режиме. Если значения совпадают, массив не является многомерным, так как многомерный массив будет иметь более высокое рекурсивное число.

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

Это второе значение параметра mode было добавлено в PHP 4.2.0. Из Документов PHP:

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

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

 172
Author: Community, 2012-08-29 02:32:53

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

function is_multi($array) {
    return (count($array) != count($array, 1));
}
 27
Author: scronide, 2008-09-29 21:02:18

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

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

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

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

 9
Author: Pian0_M4n, 2015-07-22 14:23:05

Я думаю, что это самый прямой путь, и он самый современный:

function is_multidimensional(array $array) {
    return count($array) !== count($array, COUNT_RECURSIVE);
}
 8
Author: Andreas, 2016-05-10 18:16:29

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

 7
Author: Greg Hewgill, 2008-09-28 06:25:25

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

function isMultiArray($a){
    foreach($a as $v) if(is_array($v)) return TRUE;
    return FALSE;
}
 4
Author: Joe, 2013-07-26 02:22:15

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

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

   return $return;
}
 2
Author: , 2008-09-28 06:26:18

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

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';
 2
Author: RoboTamer, 2012-03-13 04:37:43

Вы также можете выполнить простую проверку следующим образом:

$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
Author: Prashant, 2013-04-25 05:51:30

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

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

}else{

  echo 'arrayList is no multidimensional';
}
 1
Author: Arshid KV, 2016-04-01 19:25:47

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

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

    return count($result) == 1 && array_shift($result) == "array";
}
 0
Author: Alfonso Fernandez-Ocampo, 2014-10-17 00:30:10

Все вышеперечисленные методы слишком сложны для быстрого развертывания. Если массив плоский, тестирование первого элемента должно возвращать примитив, например, int, строку и т. Д. Если он многомерный, он должен возвращать массив. Таким образом, вы можете использовать этот лайнер быстро и аккуратно.

echo is_array(array_shift($myArray));

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

 0
Author: Nelson Emeka Ameyo, 2015-09-04 10:17:11

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

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
Author: RafaSashi, 2016-04-01 19:19:48

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

is_array(current($array));

Если ложно, то это одномерный массив, если истинно, то это многомерный массив.

Текущий выдаст вам первый элемент вашего массива и проверит, является ли первый элемент массивом или нет, с помощью функции is_array.

 0
Author: Priyank, 2017-04-13 13:17:26

Не используйте 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 ) );
 0
Author: hendra1, 2018-02-25 16:06:41

В моем случае. Я застрял в каком-то странном состоянии.
1-й случай = array("data"=> "name");
2-й случай = 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';
    }

Особая благодарность Винко Врсаловичу

 0
Author: Darkcoder, 2018-03-27 10:41:32

Встроенная функция 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 занял 0,83681297302246 секунды в 500000 раз"

Любезно предоставлено: Руах Хакодеш

 0
Author: Racer X, 2018-10-05 19:11:22
if($array[0]){
//enter your code 
}
 -1
Author: rthcupid, 2014-02-28 11:39:11
if ( array_key_exists(0,$array) ) {

// multidimensional array

}  else {

// not a multidimensional array

}

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

 -1
Author: sudhin babu, 2015-03-26 13:07:26
function isMultiArray(array $value)
{
    return is_array(reset($value));
}
 -2
Author: jhonatan, 2011-11-24 11:00:00
is_array($arr[key($arr)]); 

Никаких петель, просто и ясно.

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

 -3
Author: Carlos, 2012-03-13 04:34:15