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

StackOverflow https://stackoverflow.com/questions/145337

Вопрос

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

Решение

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

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)

Другие советы

Используйте 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()).

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

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

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

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

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

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

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

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

Вы могли бы посмотреть, проверить 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';
}

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

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

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

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

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

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

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

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

В моем случае.Я застрял в каком-то странном состоянии.
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';
    }

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

Это так же просто, как

$isMulti = !empty(array_filter($array, function($e) {
                    return is_array($e);
                }));
if($array[0]){
//enter your code 
}
if ( array_key_exists(0,$array) ) {

// multidimensional array

}  else {

// not a multidimensional array

}

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

Встроенная функция 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 раз".

Вежливость:Руах Хакодеш

function isMultiArray(array $value)
{
    return is_array(reset($value));
}
is_array($arr[key($arr)]); 

Никаких зацикливаний, все просто.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top