递归嵌套对象

时间:2012-01-18 01:27:08

标签: php recursion

我有一个包含嵌套对象的对象,依此类推。嵌套级别可以假定为无限。

如果对象嵌套其他对象,则子项应存储在名为childElements的数组属性中。

我正在使用的对象如下所示:

Object
   childElements
       ['object1'] => object
                         childElements
                            ['object11'] => object

       ['object2'] => object

我想使用递归来引用名为object11的对象。这是我正在使用的功能。函数驻留在一个类中,因此在调用递归时使用$this

public function recursiveSearch(array $childElements, $elementName){
    foreach ($childElements as $key => $element) {
        var_dump($key);
        if (isset($element->childElements)){

            return $this->recursiveSearch($element->childElements, $elementName);

        }else{
            if ($key == $elementName){
                return $childElements[$elementName];
            }
        }
    }

    throw new Exception("$elementName could not be found.");
}

然后我调用我的函数(假设该对象被称为$r):

return $this->recursiveSearch($r->childElements, 'object11');

我的代码存在问题(查看var转储时,函数将继续向最内层对象移动。但是一旦完成,它就会终止,无论它是否访问过任何其他childElements我认为这个问题是由于return $this->recursiveSearch导致过早的回归。

如何构建递归函数以使其正常工作?

2 个答案:

答案 0 :(得分:3)

我相信你的逻辑问题在你的if-else语句中。您首先检查$ childElements是否存在,如果存在,则运行recursiveSearch。您需要先测试密钥匹配,然后检查子项。这样,如果找到它,就不会开始另一次递归。

tldr; do if(key == name){return element} else {recursionSearch}。

答案 1 :(得分:1)

问题是您的代码假定如果元素具有子元素,则该元素必须位于子元素中。实际上你需要三个条件:

  • 如果元素本身是搜索的元素,则将其返回
  • 如果该元素具有子且搜索到的元素位于这些子中,则将其返回
  • 如果上述都不是所有元素,则返回false(不要抛出异常,因为大多数孩子都没有找到该元素)

代码:

public function recursiveSearch(array $childElements, $elementName){
    foreach ($childElements as $key => $element) {
        if ($key == $elementName) {
            return $element;
        }
        if (
            !empty($element->childElements) &&
            $element = $this->recursiveSearch($element->childElements, $elementName)
        ) {
            return $element;
        }
    }
    return false;
}