Domanda

  1. Qual è il modo più efficiente per verificare se un array è un array piatto di valori primitivi o se si tratta di un array multidimensionale ?
  2. Esiste un modo per farlo senza effettivamente scorrere un array e in esecuzione is_array () su ciascuno dei suoi elementi?
È stato utile?

Soluzione

La risposta breve è no, non puoi farlo senza almeno ricorrere in modo implicito se la "seconda dimensione" potrebbe essere ovunque. Se deve essere nel primo elemento, dovresti semplicemente

is_array($arr[0]);

Ma il modo generale più efficiente che ho trovato è usare un ciclo foreach sull'array, cortocircuitando ogni volta che viene trovato un hit (almeno il loop implicito è migliore del straight per ()):

$ 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

Ciclo implicito, ma non possiamo cortocircuitare non appena viene trovata una corrispondenza ...

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

Altri suggerimenti

Usa count () due volte; una volta in modalità predefinita e una volta in modalità ricorsiva. Se i valori corrispondono, l'array è non multidimensionale, poiché un array multidimensionale avrebbe un conteggio ricorsivo più elevato.

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

Questa opzione secondo valore mode è stata aggiunta in PHP 4.2.0. Dai Documenti PHP :

  

Se il parametro della modalità opzionale è impostato su COUNT_RECURSIVE (o 1), count () conterà ricorsivamente l'array. Ciò è particolarmente utile per contare tutti gli elementi di un array multidimensionale. count () non rileva la ricorsione infinita.

Tuttavia, questo metodo non rileva array (array ()) .

Per PHP 4.2.0 o successivi:

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

Penso che questo sia il modo più diretto ed è allo stato dell'arte:

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

Puoi semplicemente eseguire questo:

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

Se il parametro della modalità opzionale è impostato su COUNT_RECURSIVE (o 1), count () conterà ricorsivamente l'array. Ciò è particolarmente utile per contare tutti gli elementi di un array multidimensionale.

Se è lo stesso, significa che non ci sono livelli secondari da nessuna parte. Facile e veloce!

Potresti guardare is_array () sul primo elemento, supponendo che se il primo elemento di un array è un array, lo sono anche gli altri.

Tutte ottime risposte ... ecco le mie tre righe che utilizzo sempre

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

Questa funzione restituirà il numero int delle dimensioni dell'array (rubato da qui ).

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

   return $return;
}

Penso che scoprirai che questa funzione è il modo più semplice, più efficiente e più veloce.

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

Puoi provarlo in questo modo:

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

Puoi anche fare un semplice controllo come questo:

$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

Prova come segue

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

}else{

  echo 'arrayList is no multidimensional';
}

Non utilizzare COUNT_RECURSIVE

fai clic su questo sito per sapere perché

usa rsort e quindi usa isset

function is_multi_array( $arr ) {
rsort( $arr );
return isset( $arr[0] ) && is_array( $arr[0] );
}
//Usage
var_dump( is_multi_array( $some_array ) );

Penso che questo sia di classe (prop a un altro utente non conosco il suo nome utente):

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

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

Tutti i metodi sopra indicati sono troppo complessi per essere implementati rapidamente. Se una matrice è piatta, testare il primo elemento dovrebbe restituire una primitiva, ad esempio int, stringa e.t.c. Se è multidimensionale, dovrebbe restituire un array. Per estensione, puoi usare questa fodera in modo rapido e pulito.

echo is_array(array_shift($myArray));

se restituisce true, l'array è multidimensionale. Altrimenti è piatto. Solo per notare, è molto raro che le matrici abbiano dimensioni diverse, ad es. se stai generando dati da un modello, avrà sempre lo stesso tipo di struttura multidimensionale o piatta che può essere attraversata da loop. loop realizzati a macchina In caso contrario, lo hai personalizzato a mano, il che significa che sai dove sarà tutto e funziona senza la necessità di scrivere un algoritmo di loop inserisci qui la descrizione dell'immagine

Oltre alle risposte precedenti e in base allo schema dell'array che si desidera controllare:

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

Anche questo funziona

is_array(current($array));

Se false è un array a dimensione singola se true è un array a più dimensioni .

corrente ti fornirà il primo elemento dell'array e controllerà se il primo elemento è un array o meno mediante la funzione is_array .

Nel mio caso. Mi sono bloccato in varie condizioni strane.
1 ° caso = array (" data " = > " nome ");
2o caso = array (" data " = > array (" name " = > " username ", " fname " = > " fname "));
Ma se data ha array invece di value, la funzione sizeof () o count () non funziona per questa condizione. Quindi creo una funzione personalizzata da controllare.
Se il primo indice dell'array ha valore, allora restituisce "solo valore"
Ma se index ha un array invece di un valore, allora restituisce " ha un array "
Uso in questo modo

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

Un ringraziamento speciale a Vinko Vrsalovic

È semplice come

$isMulti = !empty(array_filter($array, function($e) {
                    return is_array($e);
                }));
if($array[0]){
//enter your code 
}
if ( array_key_exists(0,$array) ) {

// multidimensional array

}  else {

// not a multidimensional array

}

* solo per quelle matrici con indice numerico

La funzione print_r nativa restituisce una stringa leggibile dall'uomo. Basta contare il " Array " le istanze.

provare ...

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)

Sulla mia scatola, "quotato is_multi ha impiegato 0,83681297302246 secondi in 500000 volte"

Per gentile concessione: Ruach HaKodesh

function isMultiArray(array $value)
{
    return is_array(reset($value));
}
is_array($arr[key($arr)]); 

Nessun loop, chiaro e semplice.

Funziona anche con array associati, non solo array numerici, che non potrebbero contenere 0 (come nell'esempio precedente, ti darebbe un avvertimento se l'array non ha uno 0)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top