Vérifier si le tableau est multidimensionnel ou non?


137
  1. Quel est le moyen le plus efficace de vérifier si un tableau est un tableau plat de valeurs primitives ou s'il s'agit d'un tableau multidimensionnel ?
  2. Existe-t-il un moyen de le faire sans réellement parcourir un tableau et s'exécuter is_array()sur chacun de ses éléments?

9
Il est intéressant de noter que PHP n'a pas de véritables tableaux multidimensionnels - juste de simples tableaux associatifs de valeurs. Donc votre question se demande vraiment "y a-t-il une valeur non scalaire dans mon tableau"?
gahooa

21
En fait ... je ne pense pas que cela vaille la peine d'être souligné.
Joe

Réponses:


135

La réponse courte est non, vous ne pouvez pas le faire sans au moins une boucle implicite si la «deuxième dimension» peut être n'importe où. Si cela doit être dans le premier élément, vous feriez juste

is_array($arr[0]);

Mais, la manière générale la plus efficace que j'ai pu trouver est d'utiliser une boucle foreach sur le tableau, en court-circuitant chaque fois qu'un hit est trouvé (au moins la boucle implicite est meilleure que la boucle directe pour ()):

$ 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

Boucle implicite, mais on ne peut pas court-circuiter dès qu'une correspondance est trouvée ...

$ 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
Bien, avec l'avertissement que je pense que votre ligne de filtrage devrait avoir array_map ("is_array", $ a), sans utiliser is_array comme mot nu.
Matthew Scharley

Bonne prise, qui a accéléré is_multi, mais toujours pas assez bon pour correspondre à foreach
Vinko Vrsalovic

2
Il est à noter que, tel qu'il est écrit, multi_3 ne fonctionnera que sur des tableaux non associatifs à base zéro sans lacunes dans les indices, ce qui signifie qu'il n'identifiera correctement aucun de ces exemples comme multidimensionnel.
Cragmonkey

En fonction is_multi()optimiser le code en faisantreturn count($rv)>0
Xorifelse

is_array (array_values ​​($ arr) [0]) comme solution de contournement pour les clés personnalisées.
Vitor Rodrigues

191

Utilisez count () deux fois; une fois en mode par défaut et une fois en mode récursif. Si les valeurs correspondent, le tableau n'est pas multidimensionnel, car un tableau multidimensionnel aurait un nombre récursif plus élevé.

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

Cette deuxième valeur d'option a modeété ajoutée dans PHP 4.2.0. À partir des documents PHP :

Si le paramètre optionnel de mode est défini sur COUNT_RECURSIVE (ou 1), count () comptera récursivement le tableau. Ceci est particulièrement utile pour compter tous les éléments d'un tableau multidimensionnel. count () ne détecte pas la récursivité infinie.

Cependant, cette méthode ne détecte pas array(array()).


2
Comme indiqué, cela ne fonctionne pas pour les éléments avec des tableaux vides
Arthur

30

Pour PHP 4.2.0 ou plus récent:

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

Ne travaille pas pour array(array())ou pour l'un ou l' array(array(), array())autre. En général, si un tableau intérieur est vide, le décompte récursif ajoutera correctement 0 pour lui, ce qui le fera correspondre au décompte normal.
Fanis Hatzidakis

13

Je pense que c'est le moyen le plus simple et à la pointe de la technologie:

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

9

Vous pouvez simplement exécuter ceci:

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

Si le paramètre de mode facultatif est défini sur COUNT_RECURSIVE (ou 1), count () comptera le tableau de manière récursive. Ceci est particulièrement utile pour compter tous les éléments d'un tableau multidimensionnel.

Si c'est la même chose, cela signifie qu'il n'y a aucun sous-niveau nulle part. Facile et rapide!


Merci ... utile. Je voulais vérifier qu'un sous-niveau de mon tableau existait, j'ai utiliséif(count($tasks_by_date) !== count($tasks_by_date, 1))
Mike Barwick

Cool. COUNT_RECURSIVE ou 1 correspond à count ()
Pian0_M4n

Absolument. J'aime juste moins de fouillis et on a l' !==habitude de voir si le sous-niveau existe. Pour les théories qui pourraient chercher quelque chose de similaire ... etc.
Mike Barwick

Ce que vous aviez ne revenait pas vrai pour moi ... je devais ajouter le!==
Mike Barwick

Avec un tableau vide, échoue
Wallace Maxters

7

Vous pouvez vérifier is_array()le premier élément, en supposant que si le premier élément d'un tableau est un tableau, les autres le sont aussi.


C'est en fait un bon point. Dans mon cas particulier, c'est une situation soit / ou puisque je contrôle la création du tableau d'origine. Je vais laisser la question ouverte pour le moment au cas où il y aurait une solution qui pourrait fonctionner plus généralement.
Wilco du

5
Comme ça:if( is_array(current($arr)) ) { // is multidimensional }
Jonas Äppelgran

4

Toutes les bonnes réponses ... voici mes trois lignes que j'utilise toujours

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

2

Cette fonction renverra un nombre entier de dimensions de tableau (volées à partir d' ici ).

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

   return $return;
}

Cela ne fonctionnera que pour le cas de Greg. Ce n'est pas une solution générale au problème où la deuxième dimension pourrait être n'importe où dans le tableau
Vinko Vrsalovic

$ arr = array ("bonjour", "salut" => "bonjour"); $ arr [] = & arr; // oops
Tyzoid

2

Je pense que vous constaterez que cette fonction est le moyen le plus simple, le plus efficace et le plus rapide.

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

Vous pouvez le tester comme ceci:

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

si vous allez sur une seule ligne, faites au moins le tout; foreach($a as $v) is_array($v) ? return TRUE : return FALSE;
Robert Pounder

@RobertPounder ou mêmeforeach($a as $v) return is_array($v) ? true : false;
Yassine Sedrani

2

Après PHP 7, vous pouvez simplement faire:

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

1

Vous pouvez également effectuer une vérification simple comme celle-ci:

$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

Essayez comme suit

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

}else{

  echo 'arrayList is no multidimensional';
}

1

Même cela fonctionne

is_array(current($array));

Si faux, c'est un tableau à une seule dimension , si vrai, c'est un tableau à plusieurs dimensions .

current vous donnera le premier élément de votre tableau et vérifiera si le premier élément est un tableau ou non par la fonction is_array .


Ce ne sera pas fiable si vous voulez vous assurer qu'aucun autre élément n'est imbriqué non plus.
vanamerongen

1

N'utilisez pas COUNT_RECURSIVE

cliquez sur ce site pour savoir pourquoi

utilisez rsort puis utilisez isset

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

$ arr [0] ne pourrait pas être et array mais $ arr [1] pourrait être un tableau
Supun Praneeth

1

Dans mon cas. Je suis resté dans des conditions étranges.
1er cas = array("data"=> "name");
2e cas = array("data"=> array("name"=>"username","fname"=>"fname"));
Mais si dataa un tableau au lieu de valeur, la fonction sizeof () ou count () ne fonctionne pas pour cette condition. Ensuite, je crée une fonction personnalisée pour vérifier.
Si le premier index du tableau a une valeur, il retourne "seulement valeur"
Mais si l'index a un tableau au lieu d'une valeur, il retourne "a un tableau"
J'utilise de cette façon

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

Remerciements particuliers à Vinko Vrsalovic


0

Je pense que celui-ci est chic (accessoires pour un autre utilisateur je ne connais pas son nom d'utilisateur):

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

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

0

Toutes les méthodes ci-dessus sont trop complexes pour un déploiement rapide. Si un tableau est plat, le test du premier élément doit retourner une primitive, par exemple int, chaîne, etc. S'il est multidimensionnel, il doit renvoyer un tableau. Par extension, vous pouvez utiliser cette doublure rapide et soignée.

echo is_array(array_shift($myArray));

si cela renvoie true, le tableau est multidimensionnel. Sinon, c'est plat. Juste pour noter, il est très rare que les tableaux aient des dimensions différentes, par exemple si vous générez des données à partir d'un modèle, il aura toujours le même type de structure multidimensionnelle ou plate qui peut être parcourue par des boucles. boucles faites à la machine Si ce n'est pas le cas, vous l'avez construit à la main, ce qui signifie que vous savez où tout sera et que cela fonctionne sans avoir besoin d'écrire un algorithme de boucle. entrez la description de l'image ici


Cette technique ne trouve des tableaux multidimensionnels que si le premier élément est un tableau.
Cragmonkey

Soyez prudent avec l'utilisation array_shift(), car cela supprime le premier élément et réinitialise également les touches numériques! Mieux vaut l'utiliser current()si toujours des démangeaisons pour un one-liner.
Marcello Mönkemeyer

0

En plus des réponses précédentes et en fonction du schéma du tableau que vous souhaitez vérifier:

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

C'est aussi simple que

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

Voici une belle doublure. Il itère sur chaque clé pour vérifier si la valeur de cette clé est un tableau. Cela garantira le vrai


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

Au moins utiliser if (isset($array[0])) { }. Si vous êtes sûr que les index du tableau commencent à 0
Aistis

Un tableau multidimensionnel est un tableau qui contient un ou plusieurs tableaux. Cela vérifie uniquement s'il contient un élément avec une clé de zéro.
Cragmonkey

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

// multidimensional array

}  else {

// not a multidimensional array

}

* uniquement pour les tableaux avec index numérique


Un tableau multidimensionnel est un tableau qui contient un ou plusieurs tableaux. Cela vérifie uniquement s'il contient un élément avec une clé de zéro.
Cragmonkey

-1

La fonction native print_r renvoie une chaîne lisible par l'homme. Comptez simplement les instances "Array".

essayer...

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)

Sur ma boîte, "is_multi a pris 0,83681297302246 secondes en 500000 fois"

Gracieuseté: Ruach HaKodesh


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

Cela teste uniquement si le PREMIER élément est multidimensionnel.
Cragmonkey

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

Pas de boucles, claires et simples.

Fonctionne également avec les tableaux associés non seulement les tableaux numériques, qui ne peuvent pas contenir 0 (comme dans l'exemple précédent, vous enverriez un avertissement si le tableau n'a pas de 0.)


Un tableau ne peut pas être détecté sur la clé, vous devez vérifier la valeur
RoboTamer
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.