Überprüfen, ob das Array mehrdimensional ist oder nicht?

137
  1. Was ist der effizienteste Weg, um zu überprüfen, ob ein Array ein flaches Array primitiver Werte oder ein mehrdimensionales Array ist ?
  2. Gibt es eine Möglichkeit, dies zu tun, ohne tatsächlich ein Array zu durchlaufen und is_array()auf jedem seiner Elemente zu laufen ?
Wilco
quelle
9
Es sei darauf hingewiesen, dass PHP keine echten mehrdimensionalen Arrays hat - nur einfache assoziative Array-Werte. Ihre Frage lautet also wirklich: "Gibt es einen nicht skalaren Wert in meinem Array?"
Gahooa
21
Eigentlich ... ich denke nicht, dass es sich lohnt, darauf hinzuweisen.
Joe

Antworten:

135

Die kurze Antwort lautet: Nein, Sie können es nicht tun, ohne zumindest implizit eine Schleife zu erstellen, wenn sich die 'zweite Dimension' irgendwo befinden könnte. Wenn es im ersten Element sein muss, würden Sie es einfach tun

is_array($arr[0]);

Der effizienteste allgemeine Weg, den ich finden könnte, ist die Verwendung einer foreach-Schleife im Array, die kurzgeschlossen wird, wenn ein Treffer gefunden wird (zumindest ist die implizite Schleife besser als die gerade für ()):

$ 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

Implizite Schleife, aber wir können nicht kurzschließen, sobald eine Übereinstimmung gefunden wird ...

$ 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
quelle
3
Gut, mit der Einschränkung, dass Ihre Filterzeile meiner Meinung nach array_map ("is_array", $ a) haben sollte und is_array nicht als Barwort verwendet.
Matthew Scharley
Guter Fang, der is_multi beschleunigte, aber immer noch nicht gut genug, um für
jeden
2
Es ist anzumerken, dass multi_3, wie geschrieben, nur mit nicht assoziativen Arrays auf Nullbasis ohne Lücken in den Indizes funktioniert, was bedeutet, dass keines dieser Beispiele korrekt als mehrdimensional identifiziert wird.
Cragmonkey
In der Funktion is_multi()optimieren Sie den Code, indem Siereturn count($rv)>0
Xorifelse
is_array (array_values ​​($ arr) [0]) als Problemumgehung für benutzerdefinierte Schlüssel.
Vitor Rodrigues
191

Verwenden Sie count () zweimal. einmal im Standardmodus und einmal im rekursiven Modus. Wenn die Werte übereinstimmen, ist das Array nicht mehrdimensional, da ein mehrdimensionales Array eine höhere rekursive Anzahl aufweisen würde.

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

Dieser zweite Wert der Option modewurde in PHP 4.2.0 hinzugefügt. Aus den PHP-Dokumenten :

Wenn der optionale Modusparameter auf COUNT_RECURSIVE (oder 1) gesetzt ist, zählt count () das Array rekursiv. Dies ist besonders nützlich, um alle Elemente eines mehrdimensionalen Arrays zu zählen. count () erkennt keine unendliche Rekursion.

Diese Methode erkennt jedoch nicht array(array()).

Gemeinschaft
quelle
2
Wie bereits erwähnt, funktioniert dies nicht für Elemente mit leeren Arrays
Arthur
30

Für PHP 4.2.0 oder neuer:

function is_multi($array) {
    return (count($array) != count($array, 1));
}
Scronid
quelle
Ich arbeite nicht für array(array())oder auch array(array(), array())nicht. Wenn ein inneres Array leer ist, addiert die rekursive Anzahl im Allgemeinen korrekt 0 für dieses Array, sodass es mit der normalen Anzahl übereinstimmt.
Fanis Hatzidakis
13

Ich denke, dies ist der einfachste Weg und auf dem neuesten Stand der Technik:

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

Sie können dies einfach ausführen:

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

Wenn der optionale Modusparameter auf COUNT_RECURSIVE(oder 1) gesetzt ist, zählt count () das Array rekursiv. Dies ist besonders nützlich, um alle Elemente eines mehrdimensionalen Arrays zu zählen.

Wenn es dasselbe ist, bedeutet dies, dass es nirgendwo Unterebenen gibt. Einfach und schnell!

Pian0_M4n
quelle
Danke ... hilfreich. Ich wollte überprüfen, ob eine Unterebene zu meinem Array vorhanden ist, die ich verwendet habeif(count($tasks_by_date) !== count($tasks_by_date, 1))
Mike Barwick
Cool. COUNT_RECURSIVE oder 1 ist gleich für count ()
Pian0_M4n
Absolut. Ich mag nur weniger Unordnung und das !==wurde verwendet, um zu sehen, ob es eine Unterebene gibt. Für Theorien, die nach etwas Ähnlichem suchen ... usw.
Mike Barwick
Was Sie hatten, war für mich nicht wahr ... Ich musste das hinzufügen!==
Mike Barwick
Mit leerem Array ist
fehlgeschlagen
7

Sie können is_array()das erste Element überprüfen , unter der Annahme, dass, wenn das erste Element eines Arrays ein Array ist, auch der Rest von ihnen.

Greg Hewgill
quelle
Das ist eigentlich ein guter Punkt. In meinem speziellen Fall handelt es sich um eine Entweder-Oder-Situation, da ich die Erstellung des ursprünglichen Arrays steuere. Ich werde die Frage vorerst offen lassen, falls es eine Lösung gibt, die allgemeiner funktioniert.
Wilco
5
So:if( is_array(current($arr)) ) { // is multidimensional }
Jonas Äppelgran
4

Alles gute Antworten ... hier sind meine drei Zeilen, die ich immer benutze

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

Diese Funktion gibt die Anzahl der Array-Dimensionen zurück (von hier gestohlen ).

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

   return $return;
}

quelle
Dies wird nur für Gregs Fall funktionieren. Es ist keine allgemeine Lösung für das Problem, dass die zweite Dimension irgendwo im Array sein könnte
Vinko Vrsalovic
$ arr = array ("Hallo", "Hallo" => "Hallo"); $ arr [] = & arr; // oops
Tyzoid
2

Ich denke, Sie werden feststellen, dass diese Funktion der einfachste, effizienteste und schnellste Weg ist.

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

Sie können es so testen:

$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
quelle
Wenn Sie in eine Zeile gehen, machen Sie zumindest das Ganze. foreach($a as $v) is_array($v) ? return TRUE : return FALSE;
Robert Pounder
@ RobertPounder oder sogarforeach($a as $v) return is_array($v) ? true : false;
Yassine Sedrani
1

Sie können auch eine einfache Überprüfung wie folgt durchführen:

$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
quelle
1

Versuchen Sie es wie folgt

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

}else{

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

Auch das funktioniert

is_array(current($array));

Wenn false, ist es ein eindimensionales Array. Wenn true, ist es ein mehrdimensionales Array.

current gibt Ihnen das erste Element Ihres Arrays und prüft anhand der Funktion is_array , ob das erste Element ein Array ist oder nicht .

Priyank
quelle
Das ist nicht zuverlässig, wenn Sie sicherstellen möchten, dass auch kein anderes Element verschachtelt ist.
Vanamerongen
1

Verwenden Sie nicht COUNT_RECURSIVE

Klicken Sie auf diese Seite, um zu erfahren, warum

Verwenden Sie rsort und dann 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
quelle
$ arr [0] konnte nicht sein und Array, aber $ arr [1] könnte ein Array sein
Supun Praneeth
1

In meinem Fall. Ich steckte in unterschiedlichem seltsamen Zustand fest.
1. Fall = array("data"=> "name");
2. Fall = array("data"=> array("name"=>"username","fname"=>"fname"));
Wenn datajedoch ein Array anstelle eines Werts vorhanden ist, funktioniert die Funktion sizeof () oder count () für diese Bedingung nicht. Dann erstelle ich eine benutzerdefinierte Funktion zu überprüfen.
Wenn der erste Index des Arrays einen Wert hat, gibt er "nur Wert" zurück.
Wenn der Index jedoch ein Array anstelle eines Werts hat, gibt er "hat ein Array" zurück.
Ich verwende diesen Weg

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

Besonderer Dank geht an Vinko Vrsalovic

Darkcoder
quelle
1

Nach PHP 7 können Sie einfach Folgendes tun:

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

Ich denke, dieser ist edel (Requisiten an einen anderen Benutzer, dessen Benutzername ich nicht kenne):

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

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

Alle oben genannten Methoden sind zu komplex für eine schnelle Einführung. Wenn ein Array flach ist, sollte das Testen des ersten Elements ein Grundelement zurückgeben, z. B. int, string usw. Wenn es mehrdimensional ist, sollte es ein Array zurückgeben. Als Erweiterung können Sie diesen Einzeiler schnell und ordentlich verwenden.

echo is_array(array_shift($myArray));

Wenn dies true zurückgibt, ist das Array mehrdimensional. Sonst ist es flach. Zu beachten ist, dass Arrays sehr selten unterschiedliche Dimensionen haben, z. B. wenn Sie Daten aus einem Modell generieren, haben sie immer dieselbe Art von mehrdimensionaler oder flacher Struktur, die von Schleifen durchlaufen werden kann. maschinell hergestellte Schleifen Wenn dies nicht der Fall ist, haben Sie es von Hand angefertigt, was bedeutet, dass Sie wissen, wo sich alles befindet, und es funktioniert einfach, ohne dass Sie einen Schleifenalgorithmus schreiben müssen Geben Sie hier die Bildbeschreibung ein

Nelson Emeka Ameyo
quelle
Diese Technik findet nur dann mehrdimensionale Arrays, wenn das erste Element ein Array ist.
Cragmonkey
Seien Sie vorsichtig bei der Verwendung array_shift(), da es entfernt das erste Element und setzt auch numerische Tasten! Besser verwenden, current()wenn es immer noch nach einem Einzeiler juckt.
Marcello Mönkemeyer
0

Zusätzlich zu den vorherigen Antworten und abhängig vom Schema des Arrays, das Sie überprüfen möchten:

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
quelle
0

Es ist so einfach wie

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

Hier ist ein schöner Einzeiler. Es durchläuft jeden Schlüssel, um zu überprüfen, ob der Wert an diesem Schlüssel ein Array ist. Dies wird wahr sein

Dorpo
quelle
-1
if($array[0]){
//enter your code 
}
rthcupid
quelle
Zumindest verwenden if (isset($array[0])) { }. Wenn Sie sicher sind, beginnen die Indizes des Arrays von 0
Aistis
Ein mehrdimensionales Array ist ein Array, das ein oder mehrere Arrays enthält. Dies prüft nur, ob es ein Element mit einem Schlüssel von Null enthält.
Cragmonkey
-1
if ( array_key_exists(0,$array) ) {

// multidimensional array

}  else {

// not a multidimensional array

}

* nur für Arrays mit numerischem Index

Sudhin Babu
quelle
Ein mehrdimensionales Array ist ein Array, das ein oder mehrere Arrays enthält. Dies prüft nur, ob es ein Element mit einem Schlüssel von Null enthält.
Cragmonkey
-1

Die native Funktion print_r gibt eine für Menschen lesbare Zeichenfolge zurück. Zählen Sie einfach die "Array" -Instanzen.

Versuchen...

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)

Auf meiner Box hat "is_multi in 500000-mal 0,83681297302246 Sekunden gedauert"

Mit freundlicher Genehmigung von Ruach HaKodesh

Racer X.
quelle
-2
function isMultiArray(array $value)
{
    return is_array(reset($value));
}
jhonatan
quelle
Dies testet nur, ob das FIRST-Element mehrdimensional ist.
Cragmonkey
-3
is_array($arr[key($arr)]); 

Keine Schleifen, schlicht und einfach.

Funktioniert auch mit zugeordneten Arrays, nicht nur mit numerischen Arrays, die keine 0 enthalten können (wie im vorherigen Beispiel wird eine Warnung ausgegeben, wenn das Array keine 0 hat).

Carlos
quelle
Ein Array kann auf dem Schlüssel nicht erkannt werden, Sie müssen den Wert überprüfen
RoboTamer