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

php arrays loops multidimensional-array element

79220 просмотра

23 ответа

  1. Каков наиболее эффективный способ проверить, является ли массив плоским массивом примитивных значений или многомерным массивом ?
  2. Есть ли способ сделать это без фактического цикла по массиву и запуска is_array()на каждом из его элементов?
Автор: Wilco Источник Размещён: 29.07.2019 02:54

Ответы (23)


126 плюса

Решение

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

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)
Автор: Vinko Vrsalovic Размещён: 28.09.2008 06:29

180 плюса

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

Автор: zash Размещён: 15.06.2009 05:33

28 плюса

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

function is_multi($array) {
    return (count($array) != count($array, 1));
}
Автор: scronide Размещён: 29.09.2008 09:02

10 плюса

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

function is_multidimensional(array $array) {
    return count($array) !== count($array, COUNT_RECURSIVE);
}
Автор: Andreas Размещён: 10.05.2016 06:16

9 плюса

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

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

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

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

Автор: Pian0_M4n Размещён: 22.03.2014 05:28

7 плюса

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

Автор: Greg Hewgill Размещён: 28.09.2008 06:25

4 плюса

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

function isMultiArray($a){
    foreach($a as $v) if(is_array($v)) return TRUE;
    return FALSE;
}
Автор: Joe Размещён: 26.07.2013 02:22

2 плюса

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

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

   return $return;
}
Автор: creedence.myopenid.com Размещён: 28.09.2008 06:26

2 плюса

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

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';
Автор: RoboTamer Размещён: 10.06.2011 11:37

1 плюс

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

$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
Автор: Prashant Размещён: 25.04.2013 05:51

1 плюс

Попробуйте следующим образом

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

}else{

  echo 'arrayList is no multidimensional';
}
Автор: Arshid KV Размещён: 01.04.2016 07:25

1 плюс

Не используйте 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 ) );
Автор: hendra1 Размещён: 25.02.2018 04:06

0 плюса

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

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

    return count($result) == 1 && array_shift($result) == "array";
}
Автор: Alfonso Fernandez-Ocampo Размещён: 17.10.2014 12:30

0 плюса

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

echo is_array(array_shift($myArray));

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

Автор: Nelson Emeka Ameyo Размещён: 04.09.2015 10:17

0 плюса

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

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;
}
Автор: RafaSashi Размещён: 01.04.2016 07:19

0 плюса

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

is_array(current($array));

Если false, то это массив одного измерения, если true, это массив нескольких измерений .

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

Автор: Priyank Размещён: 13.04.2017 01:17

0 плюса

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

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

Автор: Darkcoder Размещён: 27.03.2018 10:41

0 плюса

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

$isMulti = !empty(array_filter($array, function($e) {
                    return is_array($e);
                }));
Автор: Mohd Abdul Mujib Размещён: 28.01.2019 01:27

-1 плюса

if($array[0]){
//enter your code 
}
Автор: rthcupid Размещён: 28.02.2014 11:39

-1 плюса

if ( array_key_exists(0,$array) ) {

// multidimensional array

}  else {

// not a multidimensional array

}

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

Автор: sudhin babu Размещён: 25.03.2015 05:09

-1 плюса

Нативная функция 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 раз»

Предоставлено Ruach HaKodesh

Автор: Racer X Размещён: 05.10.2018 04:27

-2 плюса

function isMultiArray(array $value)
{
    return is_array(reset($value));
}
Автор: jhonatan Размещён: 01.12.2010 06:09

-3 плюса

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

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

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

Автор: Carlos Размещён: 11.06.2010 02:25
Вопросы из категории :
32x32