배열이 다차원인지 아닌지 확인?


137
  1. 배열이 기본 값의 평면 배열 인지 아니면 다차원 배열 인지 확인하는 가장 효율적인 방법은 무엇입니까 ?
  2. 실제로 배열을 반복 is_array()하고 각 요소에서 실행하지 않고이 작업을 수행 할 수있는 방법이 있습니까?

9
PHP에는 진정한 다차원 배열이 없으며 단순한 연관 배열 값만 있다는 점을 지적 할 가치가 있습니다. 그래서 당신의 질문은 실제로 "내 배열에 스칼라가 아닌 값이 있습니까?"
gahooa

21
실은 ... 난 전혀 지적 할 가치가 없다고 생각합니다.
Joe

답변:


135

짧은 대답은 '두 번째 차원'이 어디든지 될 수 있다면 최소한 암시 적으로 반복하지 않고는 할 수 없다는 것입니다. 첫 번째 항목에 있어야한다면

is_array($arr[0]);

그러나 내가 찾을 수있는 가장 효율적인 일반적인 방법은 배열에서 foreach 루프를 사용하여 적중이 발견 될 때마다 단락시키는 것입니다 (적어도 암시 적 루프가 직선 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

암시 적 루핑이지만 일치하는 것을 발견하자마자 단락 할 수 없습니다 ...

$ 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
필터링 라인에는 array_map ( "is_array", $ a)가 있어야하며 is_array를 베어 워드로 사용하지 않아야합니다.
Matthew Scharley

좋은 캐치, 속도는 is_multi이지만, foreach와 비교하기에는 충분하지 않습니다
Vinko Vrsalovic

2
기록 된대로 multi_3은 인덱스에 공백이없는 0부터 시작하는 비 연관 배열에서만 작동하므로 이러한 예제를 다차원으로 올바르게 식별하지 못합니다.
Cragmonkey

기능적 is_multi()으로 코드를 최적화함으로써return count($rv)>0
Xorifelse

사용자 정의 키에 대한 임시 해결책으로 is_array (array_values ​​($ arr) [0]).
Vitor Rodrigues

191

count ()를 두 번 사용하십시오. 한 번은 기본 모드이고 한 번은 재귀 모드입니다. 값이 일치 하면 다차원 배열의 재귀 수가 더 높으므로 배열이 다차원 이 아닙니다 .

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

이 옵션의 두 번째 값 mode은 PHP 4.2.0에서 추가되었습니다. 로부터 PHP 문서 :

선택적 모드 매개 변수가 COUNT_RECURSIVE (또는 1)로 설정된 경우 count ()는 배열을 반복적으로 계산합니다. 다차원 배열의 모든 요소를 ​​계산할 때 특히 유용합니다. count ()는 무한 재귀를 감지하지 않습니다.

그러나이 방법은 감지하지 못합니다 array(array()).


2
언급했듯이 이것은 빈 배열을 가진 요소에는 적용되지 않습니다
Arthur

30

PHP 4.2.0 이상 :

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

array(array())또는 작동하지 않습니다 array(array(), array()). 일반적으로 내부 배열이 비어 있으면 재귀 카운트에 0이 올바르게 추가되어 일반 카운트와 일치합니다.
Fanis Hatzidakis

13

나는 이것이 가장 직접적인 방법이라고 생각하며 최신 기술입니다.

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

9

간단히 이것을 실행할 수 있습니다.

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

선택적 모드 매개 변수가 COUNT_RECURSIVE(또는 1)로 설정되면 count ()는 배열을 반복적으로 계산합니다. 다차원 배열의 모든 요소를 ​​계산할 때 특히 유용합니다.

동일하면 어디에도 하위 수준이 없음을 의미합니다. 쉽고 빠릅니다!


고마워 ... 도움이. 배열에 하위 수준이 있는지 확인하고 싶었습니다.if(count($tasks_by_date) !== count($tasks_by_date, 1))
Mike Barwick

멋있는. COUNT_RECURSIVE 또는 1은 count ()와 동일
Pian0_M4n

물론. 나는 덜 혼란스럽고 !==하위 수준이 존재한다는 것을 알기 위해 사용되었습니다. 비슷한 것을 찾고있는 이론을 위해 ... 등.
Mike Barwick

당신이 나를 위해 진정한 반환되지 않았습니다했다 ... 나는를 추가 할 필요!==
마이크 바윅

빈 배열로 실패했다
월러스 Maxters

7

당신은 체크를 볼 수 있었다 is_array()배열의 첫 번째 요소가 배열 인 경우, 다음 중 나머지도 있다는 가정하에, 첫 번째 요소에.


실제로 좋은 지적입니다. 필자의 경우, 원래 배열의 생성을 제어하기 때문에 상황 중 하나입니다. 더 일반적으로 작동 할 수있는 솔루션이있는 경우 지금은 질문을 열어 두겠습니다.
Wilco

5
: 이것처럼if( is_array(current($arr)) ) { // is multidimensional }
조나스 Äppelgran

4

모든 훌륭한 답변 ... 여기 내가 항상 사용하는 세 줄이 있습니다.

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

2

이 함수는 int 수의 배열 차원을 반환합니다 ( 여기 에서 도난 ).

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

   return $return;
}

이것은 Greg의 경우에만 작동합니다. 그것은 2 차원이 배열의 어느 곳에 나있을 수있는 문제에 대한 일반적인 해결책이 아닙니다
Vinko Vrsalovic

$ arr = array ( "hello", "hi"=> "hi there"); $ arr [] = & arr; // oops
Tyzoid

2

이 기능이 가장 간단하고 효율적이며 빠른 방법이라는 것을 알게 될 것입니다.

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

다음과 같이 테스트 할 수 있습니다.

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

한 줄로 가려면 적어도 모든 일을하십시오. foreach($a as $v) is_array($v) ? return TRUE : return FALSE;
Robert Pounder

@RobertPounder 또는foreach($a as $v) return is_array($v) ? true : false;
야신 Sedrani

2

PHP 7 후에 간단하게 할 수 있습니다 :

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

1

다음과 같이 간단한 검사를 수행 할 수도 있습니다.

$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

다음과 같이 시도하십시오

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

}else{

  echo 'arrayList is no multidimensional';
}

1

이것조차도 작동합니다

is_array(current($array));

만약 거짓 자사의 단일 차원의 경우 배열 진정한 자사의 다중 차원 배열입니다.

current 는 배열의 첫 번째 요소를 제공하고 첫 번째 요소가 배열인지 여부를 is_array 함수 로 확인 합니다.


다른 요소가 중첩되지 않도록하려면 신뢰할 수 없습니다.
vanamerongen


1

나의 경우에는. 나는 이상한 상태에 달라 붙었다.
첫 번째 경우 = array("data"=> "name");
두 번째 경우 = array("data"=> array("name"=>"username","fname"=>"fname"));
그러나 data값 대신 배열이 있으면 sizeof () 또는 count () 함수가이 조건에서 작동하지 않습니다. 그런 다음 확인 할 사용자 정의 기능을 만듭니다.
배열의 첫 번째 색인에 값이
있으면 "값만"을 반환 하지만 색인에 값 대신 배열이 있으면 "배열이 있음"을 반환
합니다.이 방법을 사용합니다

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

Vinko Vrsalovic 특별 감사


0

나는 이것이 고급이라고 생각합니다 (다른 사용자에게 자신의 사용자 이름을 모르는 소품).

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

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

0

위의 모든 방법은 너무 복잡하여 빠르게 배포 할 수 없습니다. 배열이 평평한 경우 첫 번째 요소를 테스트하면 기본 요소, 예를 들어 int, string 등이 반환됩니다. 다차원 인 경우 배열을 반환해야합니다. 또한이 라이너 하나를 빠르고 깔끔하게 사용할 수 있습니다.

echo is_array(array_shift($myArray));

이것이 true를 반환하면 배열은 다차원입니다. 그렇지 않으면 평평합니다. 참고로, 배열이 다른 차원을 갖는 경우는 매우 드 rare니다. 예를 들어 모델에서 데이터를 생성하는 경우 항상 루프를 통과 할 수있는 동일한 유형의 다차원 또는 평면 구조를 갖습니다. 기계 제작 루프 그렇지 않은 경우 수동으로 직접 작성 했으므로 모든 것이 어디에 있는지 알고 루프 알고리즘을 작성할 필요없이 작동합니다. 여기에 이미지 설명을 입력하십시오


이 기법은 첫 번째 요소가 배열 인 경우에만 다차원 배열을 찾습니다.
Cragmonkey

첫 번째 요소를 제거 하고 숫자 키를 재설정 array_shift()하기 때문에을 사용할 때는주의하십시오 ! current()여전히 한 줄짜리 가려움증에 더 좋습니다 .
Marcello Mönkemeyer

0

이전 답변 외에도 확인하려는 배열의 스키마에 따라 :

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
$is_multi_array = array_reduce(array_keys($arr), function ($carry, $key) use ($arr) { return $carry && is_array($arr[$key]); }, true);

여기 좋은 라이너가 있습니다. 모든 키를 반복하여 해당 키의 값이 배열인지 확인합니다. 이것은 사실을 보장합니다


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

적어도 사용하십시오 if (isset($array[0])) { }. 배열의 인덱스가 0에서 시작하는 것이 확실하다면
Aistis

다차원 배열은 하나 이상의 배열을 포함하는 배열입니다. 키가 0 인 요소가 포함되어 있는지 확인합니다.
Cragmonkey

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

// multidimensional array

}  else {

// not a multidimensional array

}

* 숫자 인덱스가있는 배열에만


다차원 배열은 하나 이상의 배열을 포함하는 배열입니다. 키가 0 인 요소가 포함되어 있는지 확인합니다.
Cragmonkey

-1

기본 print_r 함수는 사람이 읽을 수있는 문자열을 반환합니다. "배열"인스턴스를 세십시오.

시험...

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)

제 상자에서 "is_multi는 500000 번에 0.83681297302246 초 걸렸습니다"

의례 : Ruach HaKodesh


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

FIRST 요소가 다차원인지 여부 만 테스트합니다.
Cragmonkey

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

평범하고 단순한 루프가 없습니다.

0을 포함 할 수없는 숫자 배열뿐만 아니라 연관 배열에서도 작동합니다 (이전 예제와 같이 배열에 0이 없으면 경고가 표시됩니다)


배열을 키에서 감지 할 수 없습니다. 값을 확인해야합니다
RoboTamer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.