2009-12-23 12 views
2

나는 포인트 배열이나 포인트 배열 (2 차원 또는 3 차원 배열)을 받아 들여야하는 함수를 가지고있다. 나는 그것이 2 또는 3 레벨을 가지고 있는지 여부를 감지하는 신뢰할 수있는 방법을 찾고 있습니다. 문제는 내가 검사를 수행 할 배열의 키를 믿을 수 없다, 그래서이 일 :배열의 레벨 양을 올바르게 계산하는 방법은 무엇입니까?

$levels = isset($array[0][0]) && is_array($array[0][0]) ? 3 : 2; 

가 첫 번째 키는 보통 0에게 그것을하지 않을 수 ..as,하지만 난 돈 이것에 의존하고 싶지 않습니다. 그리고 어쨌든, 그렇게 하기엔 진절머리 나게 생각합니다. 최적으로, 의 수를 확인하고 싶습니다.은 전체 배열을 반복해야합니다.

array(5) { 
    [2] => array(2) { 
     [x] => 3 
     [y] => 6 
    } 
    [3] => array(2) { 
     [x] => 4 
     [y] => 8 
    } 
    ... 

그리고 세 가지 차원 배열이 배열을 포함합니다 :

다음은 배열이 어떻게 보이는지입니다.

일부 노트 :

  • 배열이 큰, 그래서 완전히 배열을 통해 반복하는 마지막 레벨의 예외와
  • 배열이 수치 순차적으로 색인 아주 좋은 옵션 (하지 않은 이 쓰는 동안
  • 배열 키 또는 0

부터 시작되지 않을 수 X와 Y)이, I는 실현 될 수있는 해결책을 온; 있는 경우 배열의 첫 번째 항목을 검사하고 새로 발견 된 배열 등에서 자체를 호출하는 재귀 함수입니다.

더 좋고 깨끗한 아이디어가 있습니까? 스칼라 값과 배열을 모두 가질 수있는 배열을 지원하기위한 보너스 포인트 (예 : 배열의 첫 번째 항목은 문자열이지만 다음은 배열 일 수 있음).

+0

PHP 배열은 실제로 배열이 아니라 트리로 구현되므로 배열에 얼마나 많은 "레벨"이 있는지 알지 못하므로 다른 방법은 없다고 생각합니다. –

답변

5

: 당신은 아직도 당신의 코드를 조금 개선하기 위해 재귀를 사용할 수 있다고 말했다되고 그건

-

if (isset $points[0][0][0]) 

그러나 배열이 희박하다면 더 어렵습니다. 기본 문제는 PHP "배열"이 실제로 1 차원 해시라는 것입니다. 트릭은 값이 또 다른 "배열"이 될 수 있다는 것입니다. 따라서 두 번째 수준에 액세스하여 해당 값 또는 배열을 확인해야합니다.

당신은 주어진 배열 만 그렇게 하나 개의 항목을 확인해야합니다에만 소수점 값, 또는 단지 다른 배열을 포함 할 것으로 예상 다시 경우 :

if (is_array(current(current($points)))) 

당신이 원하는 걸 얻을해야 다음 현재()를 함수는 현재 배열 포인터를 반환합니다 (기본적으로 첫 번째 포인터는 항상 무언가로 설정됩니다). 따라서 현재 내부 포인터 ($ points)는 $ points [0] 또는 실제 값을 가진 첫 번째 항목을 얻습니다. 현재 외부에서는 $ points [0] [0]과 같은 것을 얻을 수 있습니다.

+0

현재 (현재 ($ points)) 솔루션은이 경우에 잘 작동하므로 사용하겠습니다. 적어도 내가 알아 낸 것보다 더 깔끔하고 시작 키가 알려지지 않은 배열에서도 작동합니다. 감사! –

1

최소한 배열을 반복하지 않으면 어떻게 할 수 있는지 알 수 없습니다. 단순한 사실은 배열에있는 요소 중 하나에 추가 레벨이있을 수 있다는 것입니다. 결과적으로 모든 요소를 ​​테스트해야합니다. 당신은 당신이 시도 할 수있는 완전한 배열 또는 배열의 전체 배열을 기대한다면

/** 
* Determine the maximum depth of an array. 
* @param $input The object to test. Might be an array, or might be an int (or 
*  any other object). 
* @param $startDepth The starting depth. Will be added as an offset to the 
*  result. 
* @return The depth of the array, plus any initial offset specified in 
*   $startDepth. 
*/ 
function testDepth($input, $startDepth = 0) { 
    if (is_array($input) { 
     $max = $startDepth; 
     for ($array as $i) { 
      // Check what the depth of the given element is 
      $result = testDepth($i, $startDepth + 1); 
      // We only care about the maximum value 
      if ($result > $max) { 
       $max = $result; 
      } 
     } 
     return $max; 
    } else { 
     // This isn't an array, so it's assumed not to be a container. 
     // This doesn't add any depth to the parent array, so just return $startDepth 
     return $startDepth; 
    } 
} 

testDepth($array); 
+0

PHP와 같은 구문이 없습니다 : for ($ array as $) { 코드를 테스트 해 보셨습니까? – mrarm

1

$ levels = is_array (현재 (현재 ($ array)))? 3 : 2;

관련 문제