Dizinin çok boyutlu olup olmadığını kontrol ediyor musunuz?


137
  1. Bir dizinin ilkel değerlerin düz bir dizisi olup olmadığını veya çok boyutlu bir dizi olup olmadığını kontrol etmenin en etkili yolu nedir ?
  2. Bunu bir dizi üzerinden döngü yapmadan is_array()ve öğelerinin her birinde çalıştırmadan yapmanın bir yolu var mı ?

9
PHP'nin gerçek çok boyutlu dizilere sahip olmadığını belirtmek gerekir - sadece basit ilişkisel dizi değerleri. Yani sorunuz gerçekten "dizilimde skaler olmayan bir değer var mı?"
gahooa

21
Aslında ... Bunun hiç de değersiz olduğunu düşünmüyorum.
Joe

Yanıtlar:


135

Kısa cevap hayır, eğer 'ikinci boyut' herhangi bir yerde olabilirse, en azından dolaylı olarak döngü yapmadan yapamazsınız. İlk öğede olması gerekiyorsa,

is_array($arr[0]);

Ancak, bulabildiğim en etkili genel yol dizide bir foreach döngüsü kullanmak, bir hit bulunduğunda kısa devre yapmaktır (en azından örtük döngü düz () için daha iyidir):

$ 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

Örtülü döngü, ancak bir maç bulunur bulunmaz devreyi kısa devre yapamayız ...

$ 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)

3
İyi, filtreleme hattınızın dizi_map ("is_array", $ a) olması gerektiğine inanıyorum, is_array'ı bir bareword olarak kullanmıyorum.
Matthew Scharley

İyi yakalama, bu hızlandı, ancak yine de foreach ile eşleşecek kadar iyi değil
Vinko Vrsalovic

2
Yazıldığı gibi, multi_3'ün sadece indekslerde boşluk olmayan sıfır tabanlı ilişkisel olmayan diziler üzerinde çalışacağını, yani bu örneklerin herhangi birini çok boyutlu olarak doğru bir şekilde tanımlamayacağını belirtmek gerekir.
Cragmonkey

Fonksiyonda is_multi()kodunu optimize ederekreturn count($rv)>0
Xorifelse

is_array (dizi_değeri ($ arr) [0]) özelleştirilmiş anahtarlar için geçici bir çözüm olarak.
Vitor Rodrigues

191

Count () öğesini iki kez kullanın; bir kez varsayılan modda ve bir kez özyinelemeli modda. Değerler eşleşirse, dizi çok boyutlu değildir , çünkü çok boyutlu bir dizi daha yüksek özyinelemeli sayıma sahiptir.

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

Bu seçenek ikinci değeri modePHP 4.2.0'da eklenmiştir. Gönderen PHP Dokümanlar :

İsteğe bağlı mod parametresi COUNT_RECURSIVE (veya 1) olarak ayarlanırsa, count () yinelemeli olarak diziyi sayar. Bu özellikle çok boyutlu bir dizinin tüm elemanlarını saymak için kullanışlıdır. count () sonsuz özyineleme algılamaz.

Ancak bu yöntem tespit etmez array(array()).


2
Belirtildiği gibi, bu, boş dizileri olan öğeler için çalışmaz
Arthur

30

PHP 4.2.0 veya daha yenisi için:

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

Çalışmıyor array(array())ya array(array(), array())da çalışmıyor . Genel olarak, bir iç dizi boşsa, yinelemeli sayım doğru olarak 0 değerini ekler ve böylece normal sayıyla eşleşir.
Fanis Hatzidakis

13

Bence bu en basit yol ve son teknoloji:

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

9

Bunu sadece yürütebilirsiniz:

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

İsteğe bağlı mod parametresi COUNT_RECURSIVE(veya 1) olarak ayarlanırsa , count () diziyi yinelemeli olarak sayar. Bu özellikle çok boyutlu bir dizinin tüm elemanlarını saymak için kullanışlıdır.

Aynı ise, hiçbir yerde alt düzey olmadığı anlamına gelir. Kolay ve hızlı!


Teşekkürler ... yararlı. Dizime bir alt seviyenin var olup olmadığını kontrol etmek istedim, kullandımif(count($tasks_by_date) !== count($tasks_by_date, 1))
Mike Barwick

Güzel. COUNT_RECURSIVE veya 1 sayı () için aynı
Pian0_M4n

Kesinlikle. Daha az dağınıklığı seviyorum ve !==alt seviyenin var olduğunu görmek için kullanıldı. Benzer bir şey arayan teoriler için ... vb.
Mike Barwick

Ne vardı benim için doğru dönmüyordu ... Eklemek gerekiyordu!==
Mike Barwick

Boş dizi ile başarısız
Wallace Maxters

7

is_array()Bir dizinin ilk öğesi bir dizi ise, geri kalanlarının da olduğu varsayımı altında ilk öğeyi kontrol edebilirsiniz .


Bu aslında iyi bir nokta. Benim durumumda, orijinal dizinin oluşturulmasını kontrol ettiğim için bu bir ya da durum. Yine de daha genel olarak çalışabilecek bir çözüm olması durumunda soruyu şimdilik açık bırakacağım.
Wilco

5
if( is_array(current($arr)) ) { // is multidimensional }
Şunun

4

Tüm harika cevaplar ... İşte her zaman kullandığım üç satır

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

2

Bu işlev, dizi boyutlarının ( buradan çalınacak ) int sayısını döndürür .

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

   return $return;
}

Bu sadece Greg'in davasında işe yarayacaktır. İkinci boyutun dizide herhangi bir yerde olabileceği soruna genel bir çözüm değil
Vinko Vrsalovic 28:08

$ arr = dizi ("merhaba", "hi" => "merhaba"); $ arr [] = & arr; // ayy
Tyzoid

2

Bence bu fonksiyonun en basit, en verimli ve en hızlı yol olduğunu göreceksiniz.

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

Bu şekilde test edebilirsiniz:

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

tek satırlık olacaksanız, en azından her şeyi yapın; foreach($a as $v) is_array($v) ? return TRUE : return FALSE;
Robert Pounder

@RobertPounder veya hattaforeach($a as $v) return is_array($v) ? true : false;
Yassine Sedrani

2

PHP 7'den sonra şunları yapabilirsiniz:

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

1

Bunun gibi basit bir kontrol de yapabilirsiniz:

$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

1

Aşağıdaki gibi deneyin

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

}else{

  echo 'arrayList is no multidimensional';
}

1

Bu bile işe yarıyor

is_array(current($array));

Eğer yanlış onun bir tek boyut ise dizi gerçek onun bir çoklu boyut dizi.

current size dizinizin ilk öğesini verir ve ilk öğenin bir dizi olup olmadığını is_array işlevi ile kontrol eder.


Başka bir öğenin de yuvalanmadığından emin olmak istiyorsanız bu güvenilir olmayacaktır.
vanamerongen


1

Benim durumumda. Ben değişik garip durumda sıkışmış.
1. durum = array("data"=> "name");
2. durum = array("data"=> array("name"=>"username","fname"=>"fname"));
Ancak datadeğer yerine dizi varsa , sizeof () veya count () işlevi bu koşul için çalışmaz. Sonra kontrol etmek için özel işlev oluşturuyorum.
Dizinin ilk endeks daha sonra değeri varsa "sadece değer" return
Ama sonra dönmek yerine değerin dizi var endeksi ise "dizi vardır"
Ben bu yolu kullanmak

 function is_multi($a) {
        foreach ($a as $v) {
          if (is_array($v)) 
          {
            return "has array";
            break;
          }
          break;
        }
        return 'only value';
    }

Vinko Vrsalovic'e özel teşekkürler


0

Bence bu şık (kullanıcı adını bilmiyorum başka bir kullanıcıya sahne):

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

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

0

Yukarıdaki yöntemlerin tümü hızlı yuvarlanma için çok karmaşıktır. Bir dizi düz ise, ilk öğenin test edilmesi ilkel, örneğin int, string vb. Döndürmelidir. Çok boyutluysa, bir dizi döndürmelidir. Ek olarak, bu tek astarı hızlı ve temiz bir şekilde kullanabilirsiniz.

echo is_array(array_shift($myArray));

bu true değerini döndürürse, dizi çok boyutludur. Yoksa düz. Sadece not etmek gerekirse, dizilerin farklı boyutlara sahip olması çok nadirdir, örneğin bir modelden veri oluşturuyorsanız, her zaman döngüler tarafından geçilebilen aynı tip çok boyutlu veya düz yapıya sahip olacaktır. makine yapımı döngüler Değilse, elle özel olarak oluşturdunuz, yani her şeyin nerede olacağını biliyorsunuz ve sadece bir döngü algoritması yazmaya gerek kalmadan çalışıyor resim açıklamasını buraya girin


Bu teknik yalnızca ilk eleman bir dizi ise çok boyutlu diziler bulur.
Cragmonkey

İlk öğeyi kaldırdığı ve aynı zamanda sayısal tuşları sıfırladığı için array_shift(), kullanırken dikkatli olun ! Hala bir astar için kaşıntı varsa daha iyi kullanın . current()
Marcello Mönkemeyer

0

Önceki yanıtlara ek olarak ve kontrol etmek istediğiniz dizinin şemasına bağlı olarak:

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

0

Bu kadar basit

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

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

İşte güzel bir astar. Bu anahtardaki değerin bir dizi olup olmadığını kontrol etmek için her anahtarı tekrarlar. Bu doğru olacaktır


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

En azından kullanın if (isset($array[0])) { }. Dizinin dizinlerinin 0'dan başlayacağından eminseniz
Aistis

Çok boyutlu dizi, bir veya daha fazla dizi içeren bir dizidir. Bu, yalnızca anahtarı sıfır olan bir öğe içerip içermediğini kontrol eder.
Cragmonkey

-1
if ( array_key_exists(0,$array) ) {

// multidimensional array

}  else {

// not a multidimensional array

}

* yalnızca sayısal dizine sahip dizilere


Çok boyutlu dizi, bir veya daha fazla dizi içeren bir dizidir. Bu, yalnızca anahtarı sıfır olan bir öğe içerip içermediğini kontrol eder.
Mart'ta Cragmonkey

-1

Yerel print_r işlevi, okunabilir bir dize döndürür. "Dizi" örneklerini saymanız yeterlidir.

Deneyin...

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)

Kutumda, "is_multi 500000 kez 0.83681297302246 saniye sürdü"

Nezaket: Ruach HaKodesh


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

Bu yalnızca İLK öğenin çok boyutlu olup olmadığını test eder.
Cragmonkey

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

Döngü yok, sade ve basit.

İlişkilendirme dizileriyle de çalışır, yalnızca 0 içeremeyen sayısal dizilerle değil (önceki örnekte olduğu gibi, dizinin 0'ı yoksa size bir uyarı gönderir.)


Anahtarda bir dizi algılanamıyor, değeri kontrol etmeniz gerekiyor
RoboTamer
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.