- Який найефективніший спосіб перевірити, чи масив є плоским масивом примітивних значень чи це багатовимірний масив ?
- Чи є спосіб це зробити, не перебираючи ретельно масив і не запускаючи
is_array()
кожен його елемент?
is_array()
кожен його елемент?Відповіді:
Коротка відповідь - ні, ви не можете цього зробити, принаймні, чітко розмовляючи, якщо "другий вимір" може бути де завгодно. Якщо це має бути в першому пункті, ви просто зробите це
is_array($arr[0]);
Але найефективніший загальний спосіб, який я міг би знайти, - це використовувати цикл foreach на масиві, короткоциркулюючи щоразу, коли знайдено потрапляння (принаймні неявна петля краща, ніж пряма для ()):
$ 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 }
Ця функція поверне 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';
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 - багатомірний масив.
Поточний дасть вам перший елемент масиву і перевірить, чи є перший елемент масивом чи ні функцією 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.)