2015-11-27 261 views
0

執行功能我有這種格式的嵌套的對象(即涉及分級列表菜單項)的結構:嵌套對象PHP

class MenuStructure{ 
    public menuItems = array() ; 
} 

class MenuItem{ 
    public menuItems = array() ; 
} 

每個菜單項可以有無限嵌套多個子項。

什麼是對結構中的所有嵌套菜單項應用特定函數或基於某種檢查要求從結構中的任何地方移除特定項的最簡單方法。

有沒有類似的技術array_walk_recursive

回答

0

好的,在玩了一段時間之後到達了一個解決方案,這對其他任何人都有幫助。

對每個項目應用函數,並根據函數取消設置項目需要兩種不同的方法,因爲取消設置項目需要在父級別完成,而不是通過引用項目本身。兩者都以匿名函數作爲參數。

第一個函數循環所有項目和子項目,並將該函數直接應用於項目。第二個函數使用一個匿名匹配函數返回true或false,並根據它們是否匹配來取消設置子項。

class MenuStructure{ 

    public items = array() ; 

    public function applyFunctionToItems($function){ 
     foreach($this->items as $key => $item){ 
      $item->applyFunction($function) ; 
      $item->applyFunctionToItems($function) ; 
     } 
    } 

    public function unsetMatchingItems($match){ 
     foreach($this->items as $key => $item){ 
      if($match($item)){ 
       unset($this->items[$key]) ; 
      } ; 
      $item->unsetMatchingItems($match) ; 
     } 
    } 

} 

class MenuItem{ 

    public items = array(); 

    public function applyFunction($function){ 
     $function($this) ; 
    } 

    public function applyFunctionToItems($function){ 
     foreach($this->items as $item){ 
      $item->applyFunction($function) ; 
      $item->applyFunctionToItems($function) ; 
     }   
    } 

    public function unsetMatchingItems($match){ 
     foreach($this->items as $key => $item){ 
      if($match($item)){ 
       unset($this->items[$key]) ; 
      }; 
      $item->unsetMatchingItems($match) ; 
     } 
    } 

} 

//Use as follows: 

$menu = new MenuStructure() ; 
$menu -> populate() ; 

$menu->applyFunctionToItems(function($item){ 

    //Sets the name of all nested items in menu to 'Dave' 

    $item->name = "Dave" ; 

}) ; 


$menu->menuStructure->unsetMatchingItems(function($item){ 

    //Removes any items named 'Chris' from all levels of nesting in menu 

    if($item->name == "Chris"){ 
     return true; 
    }else{ 
     return false; 
    } 

}) ;