- Каков наиболее эффективный способ проверить, является ли массив плоским массивом примитивных значений или это многомерный массив ?
- Есть ли способ сделать это, не перебирая массив и не выполняя
is_array()каждый из его элементов?
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)
is_multi()оптимизируйте код, выполнивreturn count($rv)>0
Дважды используйте count (); один раз в режиме по умолчанию и один раз в рекурсивном режиме. Если значения совпадают, массив не является многомерным, так как многомерный массив будет иметь более высокое рекурсивное количество.
if (count($array) == count($array, COUNT_RECURSIVE))
{
echo 'array is not multidimensional';
}
else
{
echo 'array is multidimensional';
}
Второе значение этой опции modeбыло добавлено в PHP 4.2.0. Из документации PHP :
Если необязательный параметр режима установлен в COUNT_RECURSIVE (или 1), count () будет рекурсивно подсчитывать массив. Это особенно полезно для подсчета всех элементов многомерного массива. count () не обнаруживает бесконечную рекурсию.
Однако этот метод не обнаруживает array(array()).
Для PHP 4.2.0 или новее:
function is_multi($array) {
return (count($array) != count($array, 1));
}
array(array())или array(array(), array())как. Как правило, если внутренний массив пуст, рекурсивный счетчик правильно добавит для него 0, что приведет к совпадению с обычным счетчиком.
Вы можете просто выполнить это:
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))
!==раньше я видел, существует ли подуровень. Для теорий, которые могут искать что-то подобное ... и т. Д.
!==
Вы можете проверить is_array()первый элемент при условии, что если первый элемент массива является массивом, то и остальные тоже.
if( is_array(current($arr)) ) { // is multidimensional }
Эта функция вернет целое число измерений массива (украденных отсюда ).
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';
foreach($a as $v) is_array($v) ? return TRUE : return FALSE;
foreach($a as $v) return is_array($v) ? true : false;
После PHP 7 вы могли просто сделать:
public function is_multi(array $array):bool
{
return is_array($array[array_key_first($array)]);
}
Вы также можете выполнить простую проверку, например:
$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';
}
Даже это работает
is_array(current($array));
Если false - это одномерный массив, если true - многомерный массив.
current предоставит вам первый элемент вашего массива и проверит, является ли первый элемент массивом или нет, с помощью функции is_array .
Не используйте 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 ) );
В моем случае. Я попал в очень странное состояние.
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';
}
Особая благодарность Винко Врсаловичу
Я думаю, что это классно (реквизит для другого пользователя, я не знаю его имени пользователя):
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));
если это вернет истину, массив является многомерным. Остальное плоское. Следует отметить, что массивы очень редко имеют разные размеры, например, если вы генерируете данные из модели, она всегда будет иметь один и тот же тип многомерной или плоской структуры, по которой можно обходить циклы.
Если это не так, то вы создали его вручную, что означает, что вы знаете, где все будет находиться, и он просто работает без необходимости писать алгоритм цикла.

array_shift(), так как он удаляет первый элемент, а также сбрасывает цифровые клавиши! Лучше использовать, current()если все еще хочется однострочника.
В дополнение к предыдущим ответам и в зависимости от схемы массива, который вы хотите проверить:
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;
}
Это так просто, как
$isMulti = !empty(array_filter($array, function($e) {
return is_array($e);
}));
if($array[0]){
//enter your code
}
if (isset($array[0])) { }. Если вы уверены, что индексы массива начинаются с 0
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).