2010-12-26 1 views
1

메시지 보드의 모든 포럼에 대한 데이터가 포함 된 다소 큰 배열이 있습니다. 불행히도 일부 키에 대해 반복되는 항목이있는 문제가 있습니다. 배열은 부모에 의해 계층 구조로 배열되어 있기 때문에 어떤 점에서는 깊이있게됩니다.다차원 배열에서 중복 키 제거

Array 
(
    [0] => Array 
     (
      [cat_data] => Array() 
      [forum_data] => Array 
       (
        [2] => Array 
         (
          [subforums] => Array 
           (
            [6] => Array 
             (
              [subforums] => Array 
               (
                [15] => Array() 
                [16] => Array() 
               ) 
             ) 
            [7] => Array() 
            [15] => Array() 
            [16] => Array() 
           ) 
         ) 
        [3] => Array() 
       ) 
     ) 
) 

포럼 ID 6에 많은 subforums 나가 어레이의 낮은 레벨에있는 키를 반복적으로 제거해야 포럼 ID 2에 대한 많은 subforums로 반복된다. 그래서이 예제에서는 15와 16을 6의 하위로 유지하고 싶지만 2의 하위로 제거하고 싶습니다.

그냥 노트를 쓰고 있습니다. 배열을 생성하지 않습니다. 왜냐하면 배열이 생성되는 동안 중복을 제거 할 수 없기 때문입니다.

도움 주셔서 감사합니다.

답변

0

당신이해야 모든 배열을 통해 루프를 적용 http://php.net/manual/en/function.array-unique.php 편집 :

가 왜 당신에게 도랑이 맞는 새로운 배열을 생성 할 수 없습니다

이 경우 :) 작동하지 않을 것인가?

+0

하지만이 배열은 캐시되어 불필요한 데이터베이스 쿼리를 만들고 싶지 않습니다. –

1

아마도 이러한 배열을 만드는 방법을 변경해야합니다. 이런 일이 일어나지 않도록하는 것이 더 낫습니다.

편집 : 나는 볼 수 있습니다. 포럼은 얼마나 깊이 갈 수 있습니까?

+0

잠재적으로 무제한이지만 4를 초과하는 인스턴스는 없을 것입니다. –

1

(포럼의 관련 하위 등의 관련 하위처럼)이 그것을 수행해야합니다

function remove_dup_keys(array &$array) { 
    $keys = array(); 
    foreach ($array as $key => &$value) { 
     if (is_array($value)) { 
      $keys = array_merge($keys, remove_dup_keys($value)); 
     } 
    } 

    foreach ($keys as $key) { 
     if (is_numeric($key) && in_array($key, $keys)) { 
      unset($array[$key]); 
     } 
    } 

    $keys = array_merge($keys, array_keys($array)); 
    return $keys; 
} 

remove_dup_keys($yourarray); 

를 당신이 얻을 :

Array 
(
    [0] => Array 
     (
      [cat_data] => Array 
       (
       ) 
      [forum_data] => Array 
       (
        [2] => Array 
         (
          [subforums] => Array 
           (
            [6] => Array 
             (
              [subforums] => Array 
               (
                [15] => Array 
                 (
                 ) 
                [16] => Array 
                 (
                 ) 
               ) 
             ) 
            [7] => Array 
             (
             ) 
           ) 
         ) 
        [3] => Array 
         (
         ) 
       ) 
     ) 
) 
+0

감사합니다. ,하지만 계층 구조를 유지해야하기 때문에 원래 배열 구조를 유지하려고합니다. 코드가 배열을 병합합니다. –

+0

배열을 병합한다는 것은 무엇을 의미합니까? 그렇지 않습니다. 원래 배열에서 수행 된 유일한 작업은'unset '이므로 가능한 방법은 없습니다. 위의 출력을 참조하십시오. – netcoder

0

당신이 말했듯이, 당신은 단지이 배열 돌아가고있다 그것으로 무언가를 할 필요가 있습니다.

내가 추천하는 것은 배열을 걷고 다루기 쉬운 새 배열을 만드는 것입니다.

새로운 배열이 보일 것 같은 :

array(
    'forum_id' => array(
     'forum_data' => //whatever, 
     'parent_forum => // id of parent - greatest id seen as parent 
    ), 
    ... 
); 
+0

문제는 계층 구조를 인쇄하려고하기 때문에 부모가있는 배열로 이동하면 다시 원래 배열의 형식을 다시 작성해야 할 것입니다. –

0

당신이해야 재귀 함수와 배열이 같은 것을 통해 루프 :

function remove_dupes(&$arr,$keys = array()) { 
    if (is_array($arr['subforums']) { 
    $keys = remove_redundants($arr['subforums'],$keys); 
    } 
    foreach ($arr as $k => $v) { 
    if (in_array($k,$keys)) { 
     unset($arr[$k]); 
    } else { 
     $keys[] = $k; 
    } 
    } 
    return $keys; 
} 

remove_dupes($forumarray[forum_data]); 

이 먼저 깊은 부분에 갈 것이다 (때문에 첫 번째 호출은 그 자체입니다) 그리고 그것을 거꾸로 작동합니다.