2013-08-20 2 views
0

알 수없는 구조의 깊게 중첩 된 배열에서 요소 양식을 제거해야합니다 (예 : 요소를 설정 해제하기 위해 요소를 처리하기 위해 키 시퀀스가 ​​무엇인지 알 수 없음). 그러나 제거하고있는 요소에는 일관된 구조체 (stdObject)가 있으므로 전체 다차원 배열을 검색하여 찾을 수는 있지만 제거해야합니다. 이 일을 성취하는 방법에 대한 생각?다차원 배열에서 깊이 중첩 된 요소를 제거 하시겠습니까?

편집 : 이것은 내가 지금 달성하려고하는 기능입니다.

function _subqueue_filter_reference(&$where) 
{ 
    foreach ($where as $key => $value) { 
     if (is_array($value)) 
     { 
      foreach ($value as $filter_key => $filter) 
      { 
       if (isset($filter['field']) && is_string($filter['field']) && $filter['field'] == 'nodequeue_nodes_node__nodequeue_subqueue.reference') 
       { 
        unset($value[$filter_key]); 
        return TRUE; 
       } 
      } 
      return _subqueue_filter_reference($value); 
     } 
    } 
    return FALSE; 
} 

EDIT # 2 : var_dump에서 배열 구조체의 잘린.

  • 필드
  • 값 그래서이 전체 구조 $array 할당된다고 가정
    array (size=1) 
        1 => 
        array (size=3) 
         'conditions' => 
         array (size=5) 
          0 => 
          array (size=3) 
           ... 
          1 => 
          array (size=3) 
           ... 
          2 => 
          array (size=3) 
           ... 
          3 => 
          array (size=3) 
           ... 
          4 => 
          array (size=3) 
           ... 
         'args' => 
         array (size=0) 
          empty 
         'type' => string 'AND' (length=3) 
    

    는 ..., I를 제거하는 데 필요한 요소는 타겟 세 필드 배열 인 $array[1]['conditions'][4]
  • 연산자

... 모두 문자열 값입니다. 이 문제를 해결하기 위해

+0

http://stackoverflow.com/questions/369602/delete-an-element-from-an-array?rq=1 –

+0

나는 이미 이것을 읽었으며 내 질문에 답하지 않습니다. 깊게 중첩 된 요소에 대한 정확한 키 시퀀스를 알고 있다면'unset '을 사용하는 것이 쉽지만, 그렇지 않습니다. –

+0

당신은 그것을 검색해야한다는 것을 알고 있습니다. 그래서 그것을 발견했을 때 사용하지 않는 것이 좋습니다. –

답변

0

한 가지 방법은 두 번째 매개 변수로 재귀 기능을 확장했다 :

function _subqueue_filter_reference(&$where, $keyPath = array()) 

당신은 여전히 ​​초기 호출 같은 방법으로 할 싶지만, 자체 내부 호출이 될 것이다 :

return _subqueue_filter_reference($value, array_merge($keyPath, array($key))); 

이렇게하면 $keyPath 변수의 현재 배열 부분에 도달하는 키의 전체 경로를 제공합니다. 그런 다음 unset에서 사용할 수 있습니다. 만약 당신이 정말로 더러운 느낌이 들면을 올바른 단축키로 사용할 수도 있습니다. 왜냐하면 입력 소스가 사용자의 제어 범위에 완전히 들어 있기 때문입니다.

편집 : 또 다른 참고로, 반복 할 때 배열에서 항목을 삭제하는 것은 좋지 않을 수 있습니다. foreach가 어떻게 컴파일되는지 모르겠지만 이상한 오류가 발생하면 논리를 삭제하는 것과 논리를 구분할 수 있습니다.

0

이것은 커서 문제 일뿐입니다.

function recursive_unset(&$array) 
{ 
    foreach ($array as $key => &$value) # See the added & here. 
    { 
     if(is_array($value)) 
     { 
      if(isset($value['field']) && $value['field'] == 'nodequeue_nodes_node__nodequeue_subqueue.reference') 
      { 
       unset($array[$key]); 
      } 
      recursive_unset($value); 
     } 
    } 
} 

주 : 문자열로 비교하고 그 값이 존재하는 여기 is_string 사용할 필요가 없습니다, 당신은 단지 비교를 할 수 있습니다.

귀하의 가치가 한 번만 나오기 전까지는 수익을 사용하지 마십시오.

편집 : 여기

당신이 보여 것과 비슷한 배열을 가진 완벽한 예입니다 : 나는에서 발견 된 기능의 스핀 오프 인 솔루션에 도착했습니다

$test = array (
     1 => array (
       'conditions' => 
       array (
         0 => array ('field' => 'dont_care1', 'value' => 'test', 'operator' => 'whatever'), 
         1 => array ('field' => 'dont_care2', 'value' => 'test', 'operator' => 'whatever'), 
         2 => array ('field' => 'nodequeue_nodes_node__nodequeue_subqueue.reference', 'value' => 'test', 'operator' => 'whatever'), 
         3 => array ('field' => 'dont_care3', 'value' => 'test', 'operator' => 'whatever') 
       ), 
     'args' => array(), 
     'type' => 'AND' 
)); 

var_dump($test); 

function recursive_unset(&$array) 
{ 
    foreach ($array as $key => &$value) 
    { 
     if(is_array($value)) 
     { 
      if(isset($value['field']) && $value['field'] == 'nodequeue_nodes_node__nodequeue_subqueue.reference') 
      { 
       unset($array[$key]); 
      } 
      recursive_unset($value); 
     } 
    } 
} 

recursive_unset($test); 

var_dump($test); 
+0

불행히도 작동하지 않습니다. –

+0

3 차원 배열에서이 코드를 테스트 한 결과 작동했습니다. '필드'가 배열의 첫 번째 레벨에 있었 더라면 (배열 자체는 삭제하지 않음) 작동하지 않을 것입니다. – Kethryweryn

+0

검색중인 배열 구조의 샘플을 추가했습니다. –

0

http://www.php.net/manual/en/function.array-search.php#79535 (array_search 문서).

코드 : 나는 그것이 보안 구멍을 입을 딱 벌리고, 거대한의 비명 소리로 평가 사용하는 것을 싫어

function _subqueue_filter_reference($haystack,&$tree=array(),$index="") 
{ 
    // dpm($haystack); 
    if (is_array($haystack)) 
    { 

     $result = array(); 

     if (count($tree)==0) 
     { 
      $tree = array() + $haystack; 
     } 

     foreach($haystack as $k=>$current) 
     { 
      if (is_array($current)) 
      { 
       if (isset($current['field']) && is_string($current['field']) && $current['field'] == 'nodequeue_nodes_node__nodequeue_subqueue.reference') 
       { 
        eval("unset(\$tree{$index}[{$k}]);"); // unset all elements = empty array 
       } 
       _subqueue_filter_reference($current,$tree,$index."[$k]"); 
      } 
     } 
    } 
    return $tree; 
} 

하지만 꽤 안전한이고 값이 평가에서 호출되는 드루팔 코어와 조회수에 의해 명시 적으로 생성됩니다. 나는 지금 그것을 사용하는 것으로 괜찮습니다.

어쨌든 내가 트리를 반환하면 단순히 이전 배열을 새로 반환 된 트리 배열로 바꿉니다. 매력처럼 작동합니다.

관련 문제