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

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

Стоит отметить, что в PHP нет настоящих многомерных массивов - только простые ассоциативные массивы значений. Итак, ваш вопрос действительно спрашивает: «Есть ли в моем массиве нескалярное значение»?

gahooa 17.05.2010 06:50

На самом деле ... Я не думаю, что на это стоит вообще указывать.

Joe 26.07.2013 06:14
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
142
2
97 680
25
Перейти к ответу Данный вопрос помечен как решенный

Ответы 25

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

На самом деле это хороший аргумент. В моем конкретном случае это ситуация «или / или», поскольку я контролирую создание исходного массива. Я оставлю вопрос пока открытым, на случай, если есть решение, которое может работать в более общем плане.

Wilco 28.09.2008 10:27

Как это: if ( is_array(current($arr)) ) { // is multidimensional }

Jonas Äppelgran 31.03.2014 17:51

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

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

   return $return;
}

Это сработает только в случае Грега. Это не общее решение проблемы, когда второе измерение может быть где угодно в массиве.

Vinko Vrsalovic 28.09.2008 10:38

$ arr = array ("привет", "привет" => "привет"); $ arr [] = & arr; // упс

Tyzoid 08.07.2013 18:12
Ответ принят как подходящий

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

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)

Хорошо, с оговоркой, что я считаю, что ваша строка фильтрации должна иметь array_map ("is_array", $ a), а не использовать is_array как голое слово.

Matthew Scharley 28.09.2008 10:54

Хороший улов, который ускорил is_multi, но все еще недостаточно хорош, чтобы соответствовать foreach

Vinko Vrsalovic 28.09.2008 10:59

Стоит отметить, что, как написано, multi_3 будет работать только с неассоциативными массивами с отсчетом от нуля без пробелов в индексах, что означает, что он не будет правильно идентифицировать ни один из этих примеров как многомерный.

CragMonkey 19.03.2016 22:50

В функции is_multi() оптимизируйте код, выполнив return count($rv)>0

Xorifelse 02.09.2016 19:50

is_array (array_values ​​($ arr) [0]) как обходной путь для настраиваемых ключей.

Vitor Rodrigues 18.01.2019 16:55

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

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

Не работает ни для array(array()), ни для array(array(), array()). Как правило, если внутренний массив пуст, рекурсивный счетчик правильно добавит для него 0, что приведет к тому, что он будет соответствовать нормальному счетчику.

Fanis Hatzidakis 05.10.2016 16:13

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

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

В этой опции второе значение mode было добавлено в PHP 4.2.0. С Документы PHP:

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.

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

Как уже отмечалось, это не работает для элементов с пустыми массивами

Arthur 09.02.2017 08:51

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

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

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

По ключу массив не обнаруживается, необходимо проверить значение

RoboTamer 10.06.2011 15:39

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

Это только проверяет, является ли ПЕРВЫЙ элемент многомерным.

CragMonkey 19.03.2016 22:53

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

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

если вы собираетесь использовать одну строчку, по крайней мере, сделайте все; foreach($a as $v) is_array($v) ? return TRUE : return FALSE;

Robert Pounder 29.08.2017 17:06

@RobertPounder или даже foreach($a as $v) return is_array($v) ? true : false;

Yassine Sedrani 07.12.2019 22:49

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

$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

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

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

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

По крайней мере, используйте if (isset($array[0])) { }. Если вы уверены, что индексы массива начинаются с 0

Aistis 10.12.2014 00:23

Многомерный массив - это массив, содержащий один или несколько массивов. Это только проверяет, содержит ли он элемент с нулевым ключом.

CragMonkey 19.03.2016 23:01

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

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

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

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

Спасибо ... полезно. Я хотел проверить, существует ли подуровень в моем массиве, я использовал if (count($tasks_by_date) !== count($tasks_by_date, 1))

Mike Barwick 24.03.2015 06:06

Здорово. COUNT_RECURSIVE или 1 то же самое для count ()

Pian0_M4n 24.03.2015 21:58

Абсолютно. Мне просто нравится меньше беспорядка, и !== использовался, чтобы увидеть, существует ли подуровень. Для теорий, которые могут искать что-то подобное ... и т. д.

Mike Barwick 24.03.2015 22:27

То, что у вас было, не вернулось для меня ... Мне нужно было добавить !==

Mike Barwick 24.03.2015 22:28

С пустым массивом не работает

Wallace Maxters 12.08.2016 21:43

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

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

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

if ( array_key_exists(0,$array) ) {

// multidimensional array

}  else {

// not a multidimensional array

}

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

Многомерный массив - это массив, содержащий один или несколько массивов. Это только проверяет, содержит ли он элемент с нулевым ключом.

CragMonkey 19.03.2016 23:00

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

echo is_array(array_shift($myArray));

если это вернет истину, массив является многомерным. Остальное плоское. Следует отметить, что массивы очень редко имеют разные размеры, например. если вы генерируете данные из модели, она всегда будет иметь многомерную или плоскую структуру одного и того же типа, по которой можно перемещаться с помощью циклов. machine made loops Если это не так, то вы создали его вручную, что означает, что вы знаете, где все будет находиться, и он просто работает без необходимости писать алгоритм цикла.

Этот метод находит многомерные массивы только в том случае, если первый элемент является массивом.

CragMonkey 19.03.2016 23:04

Будьте осторожны при использовании array_shift(), поскольку он удаляет является первым элементом, а также сбрасывает цифровые клавиши! Лучше использовать current(), если все еще хочется однострочника.

Marcello Mönkemeyer 10.02.2017 23:42

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

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

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

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

}else{

  echo 'arrayList is no multidimensional';
}

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

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

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

is_array(current($array));

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

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

Это будет ненадежно, если вы хотите убедиться, что любой другой элемент также не вложен.

vanamerongen 21.12.2017 20:05

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

$ arr [0] не может быть массивом, но $ arr [1] может быть массивом

Supun Praneeth 27.11.2018 20:29

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

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

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

Предоставлено: Руах ха-Кодеш

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

$isMulti = !empty(array_filter($array, function($e) {
                    return is_array($e);
                }));

$is_multi_array = array_reduce(array_keys($arr), function ($carry, $key) use ($arr) { return $carry && is_array($arr[$key]); }, true);

Вот хороший лайнер. Он перебирает каждый ключ, чтобы проверить, является ли значение этого ключа массивом. Это обеспечит истинное

После PHP 7 вы могли просто сделать:

public function is_multi(array $array):bool
{
    return is_array($array[array_key_first($array)]);
}

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