【问题标题】:Recursing nested objects递归嵌套对象
【发布时间】:2012-02-12 19:30:27
【问题描述】:

我有一个包含嵌套对象等的对象。可以假设嵌套的级别是无限的。

如果对象嵌套了其他对象,则子对象应存储在名为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 导致过早返回。

如何构造我的递归函数以使其正常工作?

【问题讨论】:

    标签: php recursion


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      • 如果元素本身是搜索到的元素,则返回它
      • 如果元素有子元素并且搜索到的元素在这些子元素中,则返回它
      • 如果以上都不是所有元素,则返回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;
      }
      

      【讨论】:

        猜你喜欢
        • 2021-05-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-27
        • 2019-09-15
        • 2019-11-23
        • 2020-10-06
        • 2020-01-26
        相关资源
        最近更新 更多