2013-08-20 113 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 (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) 

...所以假設這整個結構被分配給$array,我需要刪除該元素是$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中使用它。如果你感覺真的很髒,你甚至可以使用eval作爲有效的快捷方式,因爲你給它的輸入源將完全在你的控制之內。

編輯:另一方面,從循環中刪除項目可能不是一個好主意。我不確定一個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#79535array_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; 
} 
我討厭它慘叫了巨大的,巨大的安全孔使用eval

,但它是相當安全的和值被稱爲EVAL由Drupal核心和意見明確生成。我現在可以使用它。

無論如何,當我返回樹時,我只需用新返回的樹數組替換舊數組。奇蹟般有效。