Memeriksa apakah array multidimensi atau tidak?

140
  1. Apa cara paling efisien untuk memeriksa apakah sebuah array adalah array datar dari nilai primitif atau apakah itu adalah array multidimensi ?
  2. Apakah ada cara untuk melakukan ini tanpa benar-benar melakukan perulangan melalui array dan menjalankan is_array()setiap elemennya?
Wilco
sumber
9
Perlu ditunjukkan bahwa PHP tidak memiliki array multi-dimensi yang sebenarnya - hanya nilai array asosiatif yang sederhana. Jadi pertanyaan Anda benar-benar menanyakan "apakah ada nilai non-skalar dalam array saya"?
gahooa
21
Sebenarnya ... Saya rasa itu sama sekali tidak layak untuk disebutkan.
Joe

Jawaban:

137

Jawaban singkatnya adalah tidak, Anda tidak dapat melakukannya tanpa setidaknya mengulang secara implisit jika 'dimensi kedua' bisa berada di mana saja. Jika harus di item pertama, Anda tinggal melakukannya

is_array($arr[0]);

Tapi, cara umum paling efisien yang bisa saya temukan adalah dengan menggunakan loop foreach pada array, shortcircuiting setiap kali hit ditemukan (setidaknya loop implisit lebih baik daripada 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

Perulangan implisit, tetapi kita tidak dapat melakukan hubungan singkat segera setelah kecocokan ditemukan ...

$ 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)
Vinko Vrsalovic
sumber
3
Bagus, dengan peringatan bahwa saya percaya bahwa baris pemfilteran Anda harus memiliki array_map ("is_array", $ a), bukan menggunakan is_array sebagai bareword.
Matthew Scharley
Tangkapan yang bagus, yang mempercepat is_multi, tetapi masih belum cukup bagus untuk menyamai foreach
Vinko Vrsalovic
2
Perlu dicatat bahwa, seperti yang tertulis, multi_3 hanya akan bekerja pada array non-asosiatif berbasis nol tanpa celah dalam indeks, yang berarti ia tidak akan mengidentifikasi dengan benar contoh-contoh ini sebagai multi-dimensi.
Cragmonkey
Dalam fungsinya is_multi()mengoptimalkan kode dengan melakukanreturn count($rv)>0
Xorifelse
is_array (array_values ​​($ arr) [0]) sebagai solusi untuk kunci yang disesuaikan.
Vitor Rodrigues
196

Gunakan count () dua kali; satu kali dalam mode default dan satu kali dalam mode rekursif. Jika nilainya cocok, array tersebut tidak multidimensi, karena array multidimensi akan memiliki jumlah rekursif yang lebih tinggi.

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

Nilai kedua opsi modeini ditambahkan di PHP 4.2.0. Dari Dokumen PHP :

Jika parameter mode opsional disetel ke COUNT_RECURSIVE (atau 1), count () akan menghitung larik secara rekursif. Ini sangat berguna untuk menghitung semua elemen dari array multidimensi. count () tidak mendeteksi rekursi tak terbatas.

Namun metode ini tidak mendeteksi array(array()).

Komunitas
sumber
2
Seperti disebutkan, ini tidak berfungsi untuk elemen dengan larik kosong
Arthur
30

Untuk PHP 4.2.0 atau yang lebih baru:

function is_multi($array) {
    return (count($array) != count($array, 1));
}
scronide
sumber
Tidak bekerja untuk array(array())atau array(array(), array())keduanya. Secara umum, jika array dalam kosong maka hitungan rekursif akan menambahkan 0 dengan benar untuk itu, sehingga membuatnya cocok dengan hitungan normal.
Fanis Hatzidakis
13

Saya pikir ini adalah cara yang paling lurus ke depan dan canggih:

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

Anda cukup menjalankan ini:

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

Jika parameter mode opsional disetel ke COUNT_RECURSIVE(atau 1), count () akan menghitung larik secara rekursif. Ini sangat berguna untuk menghitung semua elemen dari array multidimensi.

Jika sama, berarti tidak ada sublevel di mana pun. Mudah dan cepat!

Pian0_M4n
sumber
Terima kasih ... membantu. Saya ingin memeriksa bahwa sub level ke array saya ada, saya menggunakanif(count($tasks_by_date) !== count($tasks_by_date, 1))
Mike Barwick
Keren. COUNT_RECURSIVE atau 1 sama untuk hitungan ()
Pian0_M4n
Benar. Saya hanya suka lebih sedikit kekacauan dan yang !==digunakan untuk melihat ada sub level. Untuk teori yang mungkin mencari sesuatu yang serupa ... dll.
Mike Barwick
Apa yang Anda tidak membalas benar untuk saya ... Saya perlu menambahkan!==
Mike Barwick
Dengan larik kosong, gagal
Wallace Maxters
7

Anda bisa memeriksa is_array()elemen pertama, dengan asumsi bahwa jika elemen pertama dari sebuah array adalah sebuah array, maka sisanya juga.

Greg Hewgill
sumber
Itu sebenarnya poin yang bagus. Dalam kasus khusus saya, ini adalah situasi salah satu / atau karena saya mengontrol pembuatan array asli. Saya akan membiarkan pertanyaan terbuka untuk saat ini jika ada solusi yang mungkin berfungsi lebih umum.
Wilco
5
Seperti ini:if( is_array(current($arr)) ) { // is multidimensional }
Jonas Äppelgran
4

Semua jawaban bagus ... inilah tiga baris saya yang selalu saya gunakan

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

Fungsi ini akan mengembalikan jumlah int dari dimensi array (dicuri dari sini ).

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

   return $return;
}

sumber
Ini hanya akan berhasil untuk kasus Greg. Ini bukan solusi umum untuk masalah di mana dimensi kedua bisa berada di mana saja dalam array
Vinko Vrsalovic
$ arr = array ("hello", "hi" => "hai di sana"); $ arr [] = & arr; //
Ups
2

Saya rasa Anda akan menemukan bahwa fungsi ini adalah cara yang paling sederhana, paling efisien, dan tercepat.

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

Anda bisa mengujinya seperti ini:

$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';
RoboTamer
sumber
jika Anda memilih satu baris, setidaknya lakukan semuanya; foreach($a as $v) is_array($v) ? return TRUE : return FALSE;
Robert Pounder
@RobertPounder atau bahkanforeach($a as $v) return is_array($v) ? true : false;
Yassine Sedrani
2

Setelah PHP 7 Anda cukup melakukan:

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

sumber
1

Anda juga dapat melakukan pemeriksaan sederhana seperti ini:

$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
Prashant
sumber
1

Coba sebagai berikut

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

}else{

  echo 'arrayList is no multidimensional';
}
Arshid KV
sumber
1

Bahkan ini berhasil

is_array(current($array));

Jika salah itu adalah larik dimensi tunggal jika benar itu adalah multi dimensi larik .

current akan memberi Anda elemen pertama dari array Anda dan memeriksa apakah elemen pertama adalah array atau bukan dengan fungsi is_array .

Priyank
sumber
Itu tidak akan dapat diandalkan jika Anda ingin memastikan bahwa elemen lain juga tidak bersarang.
vanamerongen
1

Jangan gunakan COUNT_RECURSIVE

klik situs ini untuk mengetahui alasannya

gunakan rsort dan kemudian gunakan isset

function is_multi_array( $arr ) {
rsort( $arr );
return isset( $arr[0] ) && is_array( $arr[0] );
}
//Usage
var_dump( is_multi_array( $some_array ) );
hendra1
sumber
$ arr [0] tidak bisa dan array tapi $ arr [1] bisa jadi sebuah array
Supun Praneeth
1

Dalam kasus saya. Saya terjebak dalam berbagai kondisi aneh.
1st case = array("data"=> "name");
2nd case = array("data"=> array("name"=>"username","fname"=>"fname"));
Tetapi jika datamemiliki array sebagai pengganti nilai maka fungsi sizeof () atau count () tidak berfungsi untuk kondisi ini. Kemudian saya membuat fungsi khusus untuk diperiksa.
Jika indeks pertama dari array memiliki nilai maka itu mengembalikan "hanya nilai"
Tetapi jika indeks memiliki array daripada nilai maka itu mengembalikan "memiliki array"
Saya menggunakan cara ini

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

Terima kasih khusus kepada Vinko Vrsalovic

Darkcoder
sumber
0

Saya pikir yang ini berkelas (alat peraga untuk pengguna lain, saya tidak tahu nama penggunanya):

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

    return count($result) == 1 && array_shift($result) == "array";
}
Alfonso Fernandez-Ocampo
sumber
0

Semua metode di atas terlalu rumit untuk diluncurkan dengan cepat. Jika sebuah array datar, pengujian elemen pertama harus mengembalikan primitif misalnya int, string dll. Jika multidimensi, ia harus mengembalikan sebuah array. Dengan ekstensi, Anda bisa menggunakan liner yang satu ini dengan cepat dan rapi.

echo is_array(array_shift($myArray));

jika ini mengembalikan nilai true, array tersebut multidimensi. Lain itu datar. Sebagai catatan, sangat jarang array memiliki dimensi yang berbeda, misalnya jika Anda menghasilkan data dari model, ia akan selalu memiliki jenis struktur multidimensi atau datar yang sama yang dapat dilintasi oleh loop. mesin membuat loop Jika tidak, maka Anda telah membuatnya sendiri dengan tangan, yang berarti Anda tahu di mana semuanya akan berada dan itu hanya berfungsi tanpa perlu menulis algoritma perulangan masukkan deskripsi gambar di sini

Nelson Emeka Ameyo
sumber
Teknik ini hanya menemukan array multidimensi jika elemen pertama adalah array.
Cragmonkey
Berhati-hatilah saat menggunakannya array_shift(), karena ini menghapus elemen pertama dan juga menyetel ulang kunci numerik! Lebih baik gunakan current()jika masih gatal karena satu liner.
Marcello Mönkemeyer
0

Selain jawaban sebelumnya dan bergantung pada skema larik yang ingin Anda periksa:

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;
}
RafaSashi
sumber
0

Sesederhana itu

$isMulti = !empty(array_filter($array, function($e) {
                    return is_array($e);
                }));
Mohd Abdul Mujib
sumber
0
$is_multi_array = array_reduce(array_keys($arr), function ($carry, $key) use ($arr) { return $carry && is_array($arr[$key]); }, true);

Ini satu liner yang bagus. Ini mengulangi setiap kunci untuk memeriksa apakah nilai pada kunci itu adalah sebuah array. Ini akan memastikan kebenaran

Dorpo
sumber
-1
if($array[0]){
//enter your code 
}
rthcupid.dll
sumber
Setidaknya gunakan if (isset($array[0])) { }. Jika Anda yakin indeks array mulai dari 0
Aistis
Array multi-dimensi adalah larik yang berisi satu atau lebih larik. Ini hanya memeriksa untuk melihat apakah itu berisi elemen dengan kunci nol.
Cragmonkey
-1
if ( array_key_exists(0,$array) ) {

// multidimensional array

}  else {

// not a multidimensional array

}

* hanya untuk larik dengan indeks numerik

sudhin babu
sumber
Array multi-dimensi adalah larik yang berisi satu atau lebih larik. Ini hanya memeriksa untuk melihat apakah itu berisi elemen dengan kunci nol.
Cragmonkey
-1

Fungsi print_r asli mengembalikan string yang bisa dibaca manusia. Hitung saja contoh "Array".

mencoba...

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)

Di kotak saya, "is_multi membutuhkan 0,83681297302246 detik dalam 500000 kali"

Sumber: Ruach HaKodesh

Pembalap X
sumber
-2
function isMultiArray(array $value)
{
    return is_array(reset($value));
}
jhonatan.dll
sumber
Ini hanya menguji apakah elemen FIRST multi-dimensi.
Cragmonkey
-3
is_array($arr[key($arr)]); 

Tanpa loop, polos dan sederhana.

Berfungsi juga dengan array asosiasi tidak hanya array numerik, yang tidak bisa berisi 0 (seperti dalam contoh sebelumnya akan memberi Anda peringatan jika array tidak memiliki 0.)

Carlos
sumber
Array tidak dapat dideteksi pada kunci, Anda harus memeriksa nilainya
RoboTamer