php wert - Prüfen, ob ein Array mehrdimensional ist oder nicht?




vorhanden java (18)

  1. Was ist der effizienteste Weg zu überprüfen, ob ein Array ein flaches Array von primitiven Werten ist oder ob es ein mehrdimensionales Array ist ?
  2. Gibt es eine Möglichkeit, dies zu tun, ohne ein Array is_array() und is_array() auf jedem seiner Elemente is_array() ?

Answers

Sie können dies einfach ausführen:

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

Wenn der optionale COUNT_RECURSIVE auf COUNT_RECURSIVE (oder 1) festgelegt ist, zählt count () das Array rekursiv. Dies ist besonders nützlich zum Zählen aller Elemente eines mehrdimensionalen Arrays.

Wenn es das gleiche ist, bedeutet das, dass es nirgends Sublevel gibt. Einfach und schnell!


Auch das funktioniert

is_array(current($array));

Wenn false, dann ist es ein Single-Dimension- Array, wenn True ein Multi-Dimension- Array ist.

current liefert Ihnen das erste Element Ihres Arrays und prüft, ob das erste Element ein Array ist oder nicht, durch is_array function.


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

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

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

Ich denke, das ist der geradlinigste Weg und es ist State-of-the-Art:

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

In meinem Fall. Ich blieb in einem merkwürdigen Zustand stecken.
1. Fall = array("data"=> "name");
2. Fall = array("data"=> array("name"=>"username","fname"=>"fname"));
Wenn data jedoch Array statt Wert haben, funktioniert die Funktion sizeof () oder count () für diese Bedingung nicht. Dann erstelle ich eine benutzerdefinierte Funktion zum Überprüfen.
Wenn der erste Index des Arrays einen Wert hat, gibt er "nur Wert" zurück
Aber wenn der Index ein Array anstelle eines Wertes hat, gibt es "has array" zurück
Ich benutze 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


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

Die kurze Antwort ist nein, Sie können es nicht tun, ohne zumindest implizit zu schleifen, wenn die "zweite Dimension" irgendwo sein könnte. Wenn es im ersten Artikel sein muss, würdest du es einfach tun

is_array($arr[0]);

Aber der effizienteste Weg, den ich finden könnte, ist, eine foreach-Schleife auf dem Array zu verwenden, die immer dann kurzschließt, wenn ein Treffer gefunden wird (zumindest die implizite Schleife ist 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

Implizites Looping, aber wir können nicht kurzschließen, sobald ein Match 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)

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

Für PHP 4.2.0 oder neuer:

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

Benutze 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 hätte.

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

Dieser zweite mode wurde in PHP 4.2.0 hinzugefügt. Aus den PHP-Dokumenten :

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

Diese Methode erkennt jedoch array(array()) .


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

Du kannst 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';

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


Alle oben genannten Methoden sind zu komplex für ein schnelles Ausrollen. Wenn ein Array flach ist, sollte beim Testen des ersten Elements ein Primitiv zurückgegeben werden, zB int, string usw. Wenn es multidimensional ist, sollte es ein Array zurückgeben. Durch die Erweiterung können Sie diesen einen Liner schnell und sauber verwenden.

echo is_array(array_shift($myArray));

Wenn dies wahr zurückgibt, ist das Array multidimensional. Sonst ist es flach. Es ist zu beachten, dass Arrays sehr selten unterschiedliche Dimensionen haben. Wenn Sie z. B. Daten aus einem Modell generieren, wird immer dieselbe Art von mehrdimensionaler oder flacher Struktur verwendet, die von Schleifen durchlaufen werden kann. Wenn dies nicht der Fall ist, müssen Sie es manuell erstellen, was bedeutet, dass Sie wissen, wo alles sein wird, und es funktioniert einfach, ohne dass Sie einen Schleifenalgorithmus schreiben müssen


Verwenden Sie nicht COUNT_RECURSIVE

Klicken Sie auf diese Website, um zu erfahren, warum

Verwenden Sie rsort und verwenden Sie 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 ) );

if ( array_key_exists(0,$array) ) {

// multidimensional array

}  else {

// not a multidimensional array

}

* Nur zu diesen Arrays mit numerischem Index


Ich weiß, dass dies ein alter Beitrag ist, und es gibt bereits so viele großartige Antworten. Für ein bisschen mehr Vollständigkeit dachte ich, ich würde eine andere mit AngularJS einwerfen . Dies gilt natürlich nur, wenn Sie Angular verwenden. Natürlich möchte ich es trotzdem sagen.

angular.forEachnimmt 2 Argumente und ein optionales drittes Argument. Das erste Argument ist das Objekt (Array), über das iteriert werden soll, das zweite Argument ist die Iteratorfunktion und das optionale dritte Argument ist der Objektkontext.

Es gibt verschiedene Möglichkeiten, die forEach-Schleife zu verwenden. Das einfachste und wahrscheinlich am meisten verwendete ist

var temp = [1, 2, 3];
angular.forEach(temp, function(item) {
    //item will be each element in the array
    //do something
});

Eine andere Möglichkeit zum Kopieren von Elementen von einem Array in ein anderes ist die

var temp = [1, 2, 3];
var temp2 = [];
angular.forEach(temp, function(item) {
    this.push(item); //"this" refers to the array passed into the optional third parameter so, in this case, temp2.
}, temp2);

Sie müssen das jedoch nicht tun, Sie können einfach Folgendes tun und entspricht dem vorherigen Beispiel:

angular.forEach(temp, function(item) {
    temp2.push(item);
});

Nun gibt es Vor- und Nachteile, die angular.forEachFunktion im Gegensatz zur eingebauten Vanille- forSchleife zu verwenden.

Pros

  • Einfache Lesbarkeit
  • Einfache Beschreibbarkeit
  • Wenn verfügbar, angular.forEachwird die ES5 forEach-Schleife verwendet. Nun werde ich im Cons-Bereich effizienter arbeiten, da die forEach-Schleifen viel langsamer sind als die for-Schleifen. Ich erwähne dies als Profi, weil es schön ist, konsequent und standardisiert zu sein.

Betrachten Sie die folgenden 2 geschachtelten Schleifen, die genau dasselbe tun. Nehmen wir an, wir haben 2 Arrays von Objekten und jedes Objekt enthält ein Array von Ergebnissen, von denen jedes eine Value-Eigenschaft hat, die eine Zeichenfolge ist (oder was auch immer). Nehmen wir an, wir müssen jedes Ergebnis durchlaufen und wenn sie gleich sind, führen Sie eine Aktion aus:

angular.forEach(obj1.results, function(result1) {
    angular.forEach(obj2.results, function(result2) {
        if (result1.Value === result2.Value) {
            //do something
        }
    });
});

//exact same with a for loop
for (var i = 0; i < obj1.results.length; i++) {
    for (var j = 0; j < obj2.results.length; j++) {
        if (obj1.results[i].Value === obj2.results[j].Value) {
            //do something
        }
    }
}

Zugegeben, dies ist ein sehr einfaches hypothetisches Beispiel, aber ich habe mit dem zweiten Ansatz dreifach eingebettete Schleifen geschrieben, und es war sehr schwer zu lesen und zu schreiben.

Cons

  • Effizienz angular.forEachund das Native forEachsind beide so viel langsamer als die normale forSchleife ... etwa 90% langsamer . Halten Sie sich daher für große Datensätze am besten an die native forSchleife.
  • Keine Unterbrechung, Fortsetzung oder Rückgabe der Unterstützung. continuewird eigentlich von " accident " unterstützt, um in einer angular.forEacheinfach fortzufahren, fügen Sie eine return;Anweisung in die Funktion ein, angular.forEach(array, function(item) { if (someConditionIsTrue) return; });die dazu führt, dass sie für diese Iteration aus der Funktion heraus fortgesetzt wird. Dies ist auch auf die Tatsache zurückzuführen, dass der native forEachweder break noch weiter unterstützt.

Ich bin sicher, dass es auch andere Vor-und Nachteile gibt, und fügen Sie bitte alles hinzu, was Sie für richtig halten. Unter dem Strich denke ich, wenn Sie Effizienz brauchen, bleiben Sie bei der nativen forSchleife für Ihre Schleifenanforderungen. Wenn Ihre Datensätze jedoch kleiner sind und eine gewisse Effizienz in Kauf genommen werden kann, um Lesbarkeit und Schreibbarkeit zu erhalten, werfen Sie auf jeden Fall einen angular.forEachin diesen bösen Jungen.





php arrays loops multidimensional-array element