Sprawdzanie, czy tablica jest wielowymiarowa, czy nie?

137
  1. Jaki jest najskuteczniejszy sposób sprawdzenia, czy tablica jest płaską tablicą wartości pierwotnych, czy też tablicą wielowymiarową ?
  2. Czy istnieje sposób, aby to zrobić bez faktycznego przeglądania tablicy i uruchamiania is_array()na każdym z jej elementów?
Wilco
źródło
9
Warto podkreślić, że PHP nie ma prawdziwych tablic wielowymiarowych - tylko proste tablice asocjacyjne wartości. Twoje pytanie naprawdę brzmi „czy w mojej tablicy jest wartość nieskalarna”?
gahooa
21
Właściwie ... nie sądzę, żeby w ogóle było to warte podkreślania.
Joe

Odpowiedzi:

135

Krótka odpowiedź brzmi: nie, nie możesz tego zrobić bez przynajmniej niejawnego zapętlenia, jeśli „drugi wymiar” może być gdziekolwiek. Jeśli ma być w pierwszej pozycji, po prostu zrób

is_array($arr[0]);

Ale najbardziej wydajnym sposobem, jaki mogłem znaleźć, jest użycie pętli foreach w tablicy, skracając za każdym razem, gdy zostanie znalezione trafienie (przynajmniej niejawna pętla jest lepsza niż prosta 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

Niejawne zapętlenie, ale nie możemy zwierać, gdy tylko zostanie znalezione dopasowanie ...

$ 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
źródło
3
Dobrze, z zastrzeżeniem, że uważam, że twoja linia filtrująca powinna mieć array_map ("is_array", $ a), a nie używać is_array jako zwykłego słowa.
Matthew Scharley
Dobry chwyt, który przyspieszył is_multi, ale nadal nie jest wystarczająco dobry, aby dorównać
każdemu
2
Warto zauważyć, że, jak napisano, multi_3 będzie działać tylko na niezasocjowanych tablicach zerowych bez przerw w indeksach, co oznacza, że ​​nie zidentyfikuje poprawnie żadnego z tych przykładów jako wielowymiarowych.
Cragmonkey
W funkcji is_multi()zoptymalizuj kod, wykonującreturn count($rv)>0
Xorifelse
is_array (array_values ​​($ arr) [0]) jako obejście dla niestandardowych kluczy.
Vitor Rodrigues
191

Użyj count () dwukrotnie; jeden raz w trybie domyślnym i jeden raz w trybie rekurencyjnym. Jeśli wartości są zgodne, tablica nie jest wielowymiarowa, ponieważ tablica wielowymiarowa miałaby wyższą liczbę rekurencyjną.

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

Ta druga wartość opcji modezostała dodana w PHP 4.2.0. Z dokumentów PHP :

Jeśli opcjonalny parametr trybu jest ustawiony na COUNT_RECURSIVE (lub 1), funkcja count () będzie rekurencyjnie zliczać tablicę. Jest to szczególnie przydatne do liczenia wszystkich elementów tablicy wielowymiarowej. count () nie wykrywa nieskończonej rekurencji.

Jednak ta metoda nie wykrywa array(array()).

Społeczność
źródło
2
Jak zauważono, to nie działa dla elementów z pustymi tablicami
Arthur,
30

Dla PHP 4.2.0 lub nowszego:

function is_multi($array) {
    return (count($array) != count($array, 1));
}
skronid
źródło
Nie działa dla array(array())ani array(array(), array())jednego. Ogólnie rzecz biorąc, jeśli tablica wewnętrzna jest pusta, licznik rekurencyjny poprawnie doda do niej 0, dzięki czemu będzie pasował do normalnej liczby.
Fanis Hatzidakis
13

Myślę, że jest to najprostsza droga i najnowocześniejsza:

function is_multidimensional(array $array) {
    return count($array) !== count($array, COUNT_RECURSIVE);
}
Andreas
źródło
9

Możesz po prostu wykonać to:

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

Jeśli opcjonalny parametr trybu jest ustawiony na COUNT_RECURSIVE(lub 1), funkcja count () będzie rekurencyjnie zliczać tablicę. Jest to szczególnie przydatne do liczenia wszystkich elementów tablicy wielowymiarowej.

Jeśli jest taki sam, oznacza to, że nigdzie nie ma podpoziomów. Łatwo i szybko!

Pian0_M4n
źródło
Dzięki ... pomocna. Chciałem sprawdzić, czy istnieje poziom podrzędny mojej tablicy, użyłemif(count($tasks_by_date) !== count($tasks_by_date, 1))
Mike Barwick
Chłodny. COUNT_RECURSIVE lub 1 jest takie samo dla count ()
Pian0_M4n
Absolutnie. Po prostu lubię mniej bałaganu, a !==został użyty do zobaczenia, że ​​istnieje poziom niższy . Teorie, które mogą szukać czegoś podobnego ... itd.
Mike Barwick
To, co miałeś, nie wróciło do mnie ... Musiałem dodać!==
Mike Barwick
Z pustą tablicą zawodzi
Wallace Maxters
7

Możesz sprawdzić is_array()pierwszy element, zakładając, że jeśli pierwszy element tablicy jest tablicą, to reszta też jest.

Greg Hewgill
źródło
To właściwie dobra uwaga. W moim konkretnym przypadku jest to sytuacja typu „albo / lub”, ponieważ kontroluję tworzenie oryginalnej tablicy. Na razie pozostawię to pytanie, na wypadek gdyby było rozwiązanie, które może działać bardziej ogólnie.
Wilco
5
W ten sposób:if( is_array(current($arr)) ) { // is multidimensional }
Jonas Ęppelgran
4

Wszystkie świetne odpowiedzi ... oto moje trzy linijki, których zawsze używam

function isMultiArray($a){
    foreach($a as $v) if(is_array($v)) return TRUE;
    return FALSE;
}
Joe
źródło
2

Ta funkcja zwróci liczbę int wymiarów tablicy (skradzionych stąd ).

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

   return $return;
}

źródło
To zadziała tylko w przypadku Grega. To nie jest ogólne rozwiązanie problemu, w którym drugi wymiar może znajdować się w dowolnym miejscu w tablicy
Vinko Vrsalovic
$ arr = array ("cześć", "cześć" => "cześć"); $ arr [] = & arr; // Ups
Tyzoid,
2

Myślę, że przekonasz się, że ta funkcja jest najprostszym, najbardziej wydajnym i najszybszym sposobem.

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

Możesz to przetestować w ten sposób:

$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
źródło
jeśli zamierzasz zająć się jedną linią, zrób przynajmniej całość; foreach($a as $v) is_array($v) ? return TRUE : return FALSE;
Robert Pounder
@RobertPounder lub nawetforeach($a as $v) return is_array($v) ? true : false;
Yassine Sedrani
2

Po PHP 7 możesz po prostu zrobić:

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

źródło
1

Możesz również wykonać prostą kontrolę, taką jak ta:

$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
źródło
1

Spróbuj w następujący sposób

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

}else{

  echo 'arrayList is no multidimensional';
}
Arshid KV
źródło
1

Nawet to działa

is_array(current($array));

Jeśli fałsz jest to tablica jednowymiarowa, jeśli prawda, to tablica wielowymiarowa .

current da ci pierwszy element twojej tablicy i sprawdzi, czy pierwszy element jest tablicą, czy nie za pomocą funkcji is_array .

Priyank
źródło
Nie będzie to wiarygodne, jeśli chcesz mieć pewność, że żaden inny element również nie jest zagnieżdżony.
vanamerongen
1

Nie używaj COUNT_RECURSIVE

kliknij tę witrynę, aby dowiedzieć się, dlaczego

użyj rsort, a następnie użyj 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
źródło
$ arr [0] nie może być tablicą, ale $ arr [1] może być tablicą
Supun Praneeth
1

W moim przypadku. Utknąłem w różnych dziwnych warunkach.
Pierwszy przypadek = array("data"=> "name");
Drugi przypadek = array("data"=> array("name"=>"username","fname"=>"fname"));
Ale jeśli datama tablicę zamiast wartości, to funkcja sizeof () lub count () nie będzie działać dla tego warunku. Następnie tworzę funkcję niestandardową do sprawdzenia.
Jeśli pierwszy indeks tablicy ma wartość to zwraca "jedyną wartość"
Ale jeśli indeks ma tablicę zamiast wartości to zwraca "ma tablicę"
Używam w ten sposób

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

Specjalne podziękowania dla Vinko Vrsalovica

Darkcoder
źródło
0

Myślę, że ten jest elegancki (rekwizyty dla innego użytkownika, którego nie znam):

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

    return count($result) == 1 && array_shift($result) == "array";
}
Alfonso Fernandez-Ocampo
źródło
0

Wszystkie powyższe metody są zbyt skomplikowane, aby można je było szybko wdrożyć. Jeśli tablica jest płaska, testowanie pierwszego elementu powinno zwrócić prymityw, np. Int, string, itp. Jeśli jest wielowymiarowy, powinien zwrócić tablicę. Dzięki temu możesz używać tej jednej wkładki szybko i schludnie.

echo is_array(array_shift($myArray));

jeśli zwraca prawdę, tablica jest wielowymiarowa. W przeciwnym razie jest płaski. Warto zauważyć, że bardzo rzadko tablice mają różne wymiary, np. Jeśli generujesz dane z modelu, zawsze będzie on miał ten sam typ wielowymiarowej lub płaskiej struktury, przez którą można przechodzić przez pętle. pętle wykonane maszynowo Jeśli tak nie jest, to zbudowałeś go ręcznie, co oznacza, że ​​wiesz, gdzie wszystko będzie, i po prostu działa bez konieczności pisania algorytmu zapętlenia wprowadź opis obrazu tutaj

Nelson Emeka Ameyo
źródło
Ta technika znajduje tablice wielowymiarowe tylko wtedy, gdy pierwszy element jest tablicą.
Cragmonkey,
Zachowaj ostrożność podczas używania array_shift(), ponieważ usuwa pierwszy element, a także resetuje klawisze numeryczne! Lepiej używać, current()jeśli nadal swędzi się na jedną wkładkę.
Marcello Mönkemeyer
0

Oprócz wcześniejszych odpowiedzi iw zależności od schematu tablicy, którą chcesz sprawdzić:

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
źródło
0

To jest tak proste, jak

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

Oto ładna jedna wkładka. Iteruje po każdym kluczu, aby sprawdzić, czy wartość w tym kluczu jest tablicą. To zapewni prawdę

Dorpo
źródło
-1
if($array[0]){
//enter your code 
}
rthcupid
źródło
Przynajmniej użyj if (isset($array[0])) { }. Jeśli jesteś pewien, że indeksy tablicy zaczynają się od 0
Aistis,
Tablica wielowymiarowa to tablica zawierająca jedną lub więcej tablic. Sprawdza tylko, czy zawiera element z kluczem zerowym.
Cragmonkey
-1
if ( array_key_exists(0,$array) ) {

// multidimensional array

}  else {

// not a multidimensional array

}

* tylko do tych tablic z indeksem numerycznym

sudhin babu
źródło
Tablica wielowymiarowa to tablica zawierająca jedną lub więcej tablic. Sprawdza tylko, czy zawiera element z kluczem zerowym.
Cragmonkey
-1

Natywna funkcja print_r zwraca ciąg czytelny dla człowieka. Po prostu policz instancje „Array”.

próbować...

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)

Na moim pudełku „is_multi zajęło 0,83681297302246 sekund 500000 razy”

Dzięki uprzejmości: Ruach HaKodesh

Racer X
źródło
-2
function isMultiArray(array $value)
{
    return is_array(reset($value));
}
jhonatan
źródło
To sprawdza tylko, czy PIERWSZY element jest wielowymiarowy.
Cragmonkey
-3
is_array($arr[key($arr)]); 

Bez pętli, jasne i proste.

Działa również z tablicami skojarzonymi, a nie tylko tablicami numerycznymi, które nie mogą zawierać 0 (tak jak w poprzednim przykładzie wyświetli ostrzeżenie, jeśli tablica nie ma 0).

Carlos
źródło
Nie można wykryć tablicy na kluczu, musisz sprawdzić wartość
RoboTamer