Pergunta

  1. O que é a forma mais eficiente para verificar se uma matriz é uma matriz plana de valores primitivos ou se é uma matriz multidimensional ?
  2. Existe alguma maneira de fazer isso sem realmente looping através de um array e is_array() execução em cada um dos seus elementos?
Foi útil?

Solução

A resposta curta não é que você não pode fazê-lo sem ao menos looping implicitamente se a 'segunda dimensão' poderia estar em qualquer lugar. Se ele tem que ser no primeiro item, você tinha acabado de fazer

is_array($arr[0]);

Mas, a forma geral mais eficiente que eu poderia encontrar é usar um loop foreach sobre a matriz, curto-circuito sempre que um hit é encontrado (pelo menos o loop implícito é melhor do que o em linha reta para ()):

$ 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

looping implícita, mas não curto-circuito o mais rápido possível como uma correspondência for encontrada ...

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

Outras dicas

Use count () duas vezes; uma vez em modo padrão e um tempo no modo recursivo. Se os valores corresponderem, a matriz é não multidimensional, como uma matriz multidimensional teria uma maior contagem recursiva.

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

Esta opção segundo valor mode foi adicionado no PHP 4.2.0. Do PHP Docs :

Se o parâmetro opcional mode está definido para COUNT_RECURSIVE (ou 1), count () irá recursivamente contar a matriz. Isto é particularmente útil para a contagem de todos os elementos de uma matriz multidimensional. count () não detecta recursão infinita.

No entanto, este método não detecta array(array()).

Para PHP 4.2.0 ou mais recente:

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

Eu acho que esta é a maneira mais simples e é state-of-the-art:

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

Você pode simplesmente executar este:

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

Se o parâmetro opcional mode está definido para COUNT_RECURSIVE (ou 1), count () irá recursivamente contar a matriz. Isto é particularmente útil para a contagem de todos os elementos de uma matriz multidimensional.

Se for o mesmo, significa que não há subníveis em qualquer lugar. Fácil e rápido!

Você pode olhar cheque is_array() no primeiro elemento, sob a suposição de que se o primeiro elemento de uma matriz é uma matriz, em seguida, o resto deles são demasiado.

Todas as grandes respostas ... aqui está o meu três linhas que eu sempre estou usando

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

Esta função irá retornar número int de dimensões de matriz (roubado de aqui ).

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

   return $return;
}

Eu acho que você vai achar que esta função é o mais simples, mais eficiente, e maneira mais rápida.

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

Você pode testar assim:

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

Você também pode fazer uma verificação simples como isto:

$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

Tente o seguinte

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

}else{

  echo 'arrayList is no multidimensional';
}

Não use COUNT_RECURSIVE

clique neste site para saber por que

uso rsort e, em seguida, use isset

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

Eu acho que este é elegante (adereços para outro usuário eu não sei o seu nome de usuário):

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

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

Todos os métodos acima são demasiado complexas para uma rápida desenrolando. Se uma matriz é plana, testando o primeiro elemento deve retornar uma primitiva e.g. int, e.t.c. cadeia Se é multidimensional, ele deve retornar um array. Por extensão, você pode usar este um forro rápido e puro.

echo is_array(array_shift($myArray));

Se isso retorna true, a matriz é multidimensional. Então é plana. Apenas a nota, é muito raro para matrizes para ter diferentes dimensões, por exemplo se você estiver gerando dados a partir de um modelo, ele sempre terá o mesmo tipo de estrutura multidimensional ou apartamento que pode ser atravessado por loops. máquinas feitas loops Se não for, então você tem costume construído-lo à mão, o que significa que você sabe onde tudo vai ser e ele simplesmente funciona sem a necessidade de escrever um algoritmo de looping enter descrição da imagem aqui

Além das respostas anteriores e, dependendo do esquema da matriz que você deseja verificar:

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

Mesmo este obras

is_array(current($array));

Se false é um dimensão única array se true é um dimensão múltiplas array.

atual lhe dará o primeiro elemento de sua matriz e cheque se o primeiro elemento é um array ou não pelo função is_array.

No meu caso. I preso em variar estranha condição.
1º caso = array("data"=> "name");
2º caso = array("data"=> array("name"=>"username","fname"=>"fname"));
Mas se data tem matriz em vez de valor, em seguida, sizeof () ou count () função não trabalho para esta condição. Então eu crio função personalizada para verificação.
Se primeiro índice de gama têm valor, em seguida, retornar "único valor"
Mas se o índice tem matriz em vez de valor, em seguida, retornar "tem variedade"
Eu uso este caminho

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

Agradecimentos especiais para Vinko Vrsalovic

É tão simples como

$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

}

* Apenas para aquelas matrizes com índice numérico

A função print_r nativo retorna um string legível. Basta contar as instâncias "array".

tentar ...

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)

Em minha caixa "is_multi levou 0.83681297302246 segundos em 500000 vezes"

Cortesia: Ruach HaKodesh

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

Sem loops, simples simples e.

Obras também com matrizes associadas não só matrizes numéricos, que não poderiam conter 0 (como no exemplo anterior jogaria-lhe um aviso se a matriz não tem um 0.)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top