Checking if array is multidimensional or not?
Solution 1
The short answer is no you can't do it without at least looping implicitly if the 'second dimension' could be anywhere. If it has to be in the first item, you'd just do
is_array($arr[0]);
But, the most efficient general way I could find is to use a foreach loop on the array, shortcircuiting whenever a hit is found (at least the implicit loop is better than the straight 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
Implicit looping, but we can't shortcircuit as soon as a match is found...
$ 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)
Solution 2
Use count() twice; one time in default mode and one time in recursive mode. If the values match, the array is not multidimensional, as a multidimensional array would have a higher recursive count.
if (count($array) == count($array, COUNT_RECURSIVE))
{
echo 'array is not multidimensional';
}
else
{
echo 'array is multidimensional';
}
This option second value mode
was added in PHP 4.2.0. From the PHP Docs:
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.
However this method does not detect array(array())
.
Solution 3
For PHP 4.2.0 or newer:
function is_multi($array) {
return (count($array) != count($array, 1));
}
Solution 4
I think this is the most straight forward way and it's state-of-the-art:
function is_multidimensional(array $array) {
return count($array) !== count($array, COUNT_RECURSIVE);
}
Solution 5
You can simply execute this:
if (count($myarray) !== count($myarray, COUNT_RECURSIVE)) return true;
else return false;
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.
If it's the same, means there are no sublevels anywhere. Easy and fast!
Related videos on Youtube
Wilco
Updated on July 02, 2020Comments
-
Wilco almost 4 years
- What is the most efficient way to check if an array is a flat array of primitive values or if it is a multidimensional array?
- Is there any way to do this without actually looping through an
array and running
is_array()
on each of its elements?
-
gahooa almost 14 yearsIt's worth pointing out that PHP does not have true multi-dimensional arrays -- just simple associative array's of values. So your question is really asking "is there a non-scalar value in my array"?
-
Joe almost 11 yearsActually... I don't think that's worth pointing out at all.
-
Wilco over 15 yearsThat's actually a good point. In my particular case, it's an either/or situation since I am controlling the creation of the original array. I'll leave the question open for now in case there's a solution that might work more generally though.
-
Vinko Vrsalovic over 15 yearsThis will only work for Greg's case. It's not a general solution to the problem where the second dimension could be anywhere in the array
-
Matthew Scharley over 15 yearsGood, with the caveat that I believe that your filtering line should have array_map("is_array",$a), not using is_array as a bareword.
-
Vinko Vrsalovic over 15 yearsGood catch, that sped up is_multi, but still not good enough to match foreach
-
RoboTamer almost 13 yearsAn array can not be detected on the key, you have to check the value
-
Tyzoid almost 11 years$arr = array("hello", "hi" => "hi there"); $arr[] = &arr; //oops
-
Jonas Äppelgran about 10 yearsLike this:
if( is_array(current($arr)) ) { // is multidimensional }
-
Aistis over 9 yearsAt least use
if (isset($array[0])) { }
. If you are sure the array's indexes start from 0 -
Mike Barwick about 9 yearsThanks...helpful. I wanted to check that a sub level to my array existed, I used
if(count($tasks_by_date) !== count($tasks_by_date, 1))
-
Pian0_M4n about 9 yearsCool. COUNT_RECURSIVE or 1 is same for count()
-
Mike Barwick about 9 yearsAbsolutely. I just like less clutter and the
!==
was used to see is sub level existed. For theories who might be looking for something similar...etc. -
Mike Barwick about 9 yearsWhat you had wasn't returning true for me...I needed to add the
!==
-
CragMonkey about 8 yearsIt is worth noting that, as written, multi_3 will only work on zero-based non-associative arrays with no gaps in the indices, meaning it won't correctly identify any of these examples as multi-dimensional.
-
CragMonkey about 8 yearsThis only tests if the FIRST element is multi-dimensional.
-
CragMonkey about 8 yearsA multi-dimensional array is an array that contains one or more arrays. This only checks to see if it contains an element with a key of zero.
-
CragMonkey about 8 yearsA multi-dimensional array is an array that contains one or more arrays. This only checks to see if it contains an element with a key of zero.
-
CragMonkey about 8 yearsThis technique only finds multidimensional arrays if the first element is an array.
-
Wallace Vizerra over 7 yearsWith empty array, has fails
-
Xorifelse over 7 yearsIn function
is_multi()
optimize the code by doingreturn count($rv)>0
-
Fanis Hatzidakis over 7 yearsNot working for
array(array())
orarray(array(), array())
either. Generally, if an inside array is empty then the recursive count will correctly add 0 for it, thus making it match the normal count. -
Arthur over 7 yearsAs noted this does not work for elements with empty arrays
-
Marcello Mönkemeyer about 7 yearsBe cautious with using
array_shift()
, as it removes the first element and also resets numeric keys! Better usecurrent()
if still itching for a one-liner. -
Robert Pounder over 6 yearsif you're going to one-line it at least do the whole thing;
foreach($a as $v) is_array($v) ? return TRUE : return FALSE;
-
vanamerongen over 6 yearsThat won't be reliable if you want to ensure that any other element isn't nested either.
-
Supun Praneeth over 5 years$arr[0] could not be and array but $arr[1] could be an array
-
Vitor Rodrigues over 5 yearsis_array(array_values($arr)[0]) as a workaround for customized keys.
-
Yassine Sedrani over 4 years@RobertPounder or even
foreach($a as $v) return is_array($v) ? true : false;
-
aProgger about 2 yearsYou just check the first array element if it is an array. What if it is not but the 2nd element is an array? For example
$array = ['0' => 0, '1' => ['0' => 1]];
This is a multidim array but your function says false.