在嵌套对象php上执行功能

时间:2015-11-27 11:00:35

标签: php nested

我有这种格式的嵌套对象结构(与分层列表相关的菜单项):

class MenuStructure{
     public menuItems = array() ; 
}

class MenuItem{
    public menuItems = array() ;
}

每个菜单项可以无限期嵌套许多子项。

我最简单的方法是将特定函数应用于结构中的所有嵌套菜单项,或者根据某种检查要求从结构中的任何位置删除特定项。

是否有与array_walk_recursive相似的技术?

1 个答案:

答案 0 :(得分: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;
    }

}) ;