【问题标题】:PHP: Search and return value from multi-array with Recursive FunctionPHP:使用递归函数从多数组中搜索并返回值
【发布时间】:2017-02-27 11:37:53
【问题描述】:

我有一个多维对象数组(请参阅下面的示例数据)。现在我想在数据中搜索一个值(或属性)。如果找到该值,该函数应返回正确的对象并停止搜索。

我找到了三个使用递归函数来实现此目的的解决方案。但没有什么像上面描述的那样有效。

第一个是我自己的解决方案:

public static function getPathForUrl($folderContentDetails, string $url, $result = NULL)
{
    foreach($folderContentDetails as $key => $item)
    {
        if($item->url === $url)
        {
            $result = $item;
        }
        elseif($item->elementType === "folder")
        {
            $result = self::getPathForUrl($item->folderContent, $url, $result);
        }
    }
    return $result;
}

如果你这样调用函数:

print_r(self::getPathForUrl($data, 'order/abc/alpha');

然后它返回正确的对象。缺点是该函数搜索整个数据并最终返回结果。如果找到结果,我没有找到停止函数的方法,所以它浪费资源。

您将在网络上找到的第二种(标准)解决方案如下所示:

public static function getPathForUrl($folderContentDetails, string $url)
{
    foreach($folderContentDetails as $key => $item)    
    {
        if($url === $item->url OR ($item->elementType == "folder" && Folder::getPathForUrl($item->folderContent, $url) !== false)) 
        {
            print_r('inner: <br/>'.$item->url);
            // prints more then one value, depending on your data, in my case :
            // /order/abc/alpha
            // /order/abc
            // /order
            return $item;
        }
    }
    return false;
}

如果找到正确的值,此函数将停止。但是由于某种原因,它返回了多个对象,并且最终的对象是错误的(参见 code-cmets)。

最后一个解决方案是这样的:

public static function getPathForUrl($folderContentDetails, string $url)
{           
    foreach($folderContentDetails as $key => $item)
    {
        if($item->elementType == "folder" && $item->url != $url)
        {
            return self::getPathForUrl($item->folderContent, $url); 
            // iterates only the first sub-folder, then stops
        }
        elseif($item->url == $url)
        {
            print_r($item); //nothing, if not found in first sub-folder
            return $item; // nothing, if not found in first sub-folder
        }
    }
    return false;
}

如果你返回递归函数的结果,那么函数会下到第一个嵌套元素并停在那里,所以它不会再上去搜索其他元素。

如果您不返回结果,该函数会搜索整个数据,但当然不会返回正确的对象。

我可能没有正确理解递归的概念。非常欢迎任何帮助。

这些是一些示例数据:

Array
(
[0] => stdClass Object
    (
        [elementType] => folder
        [path] => 
        [url] => /getting-started
        [folderContent] => Array
            (
                [0] => stdClass Object
                    (
                        [elementType] => file
                        [path] => \0_getting_started\01-installation.md
                        [url] => /getting-started/installation
                    )

                [1] => stdClass Object
                    (
                        [elementType] => file
                        [path] => \0_getting_started\02-system-settings.md
                        [url] => /getting-started/system-settings
                    )

                [2] => stdClass Object
                    (
                        [elementType] => file
                        [path] => \0_getting_started\index.md
                        [url] => /getting-started/index
                    )

            )

    )

[1] => stdClass Object
    (
        [elementType] => folder
        [path] => 
        [url] => /order
        [folderContent] => Array
            (
                [0] => stdClass Object
                    (
                        [elementType] => folder
                        [path] => \2_order
                        [url] => /order/abc
                        [folderContent] => Array
                            (
                                [0] => stdClass Object
                                    (
                                        [elementType] => file
                                        [path] => \2_order\abc\alpha.md
                                        [url] => /order/abc/alpha
                                    )
                            )

                    )
            )

    )

[3] => stdClass Object
    (
        [elementType] => file
        [path] => \index.md
        [url] => /index
   )
)

【问题讨论】:

    标签: php recursion multidimensional-array


    【解决方案1】:

    Return 退出函数,所以如果你想要第一个结果,只需在你的条件下返回它

    public static function getPathForUrl($folderContentDetails, string $url, $result = NULL)
    {
        foreach($folderContentDetails as $key => $item)
        {
            if($item->url === $url)
            {
                return $item;
            }
            elseif($item->elementType === "folder")
            {
                $result = self::getPathForUrl($item->folderContent, $url, $result);
            }
        }
        return $result;
    }
    

    【讨论】:

    • 当然就这么简单 ;) 在折腾了一天之后,我只见树木不见森林,谢谢!
    【解决方案2】:

    如果您想在匹配值后停止;只需在条件内返回即可;

    public static function getPathForUrl($folderContentDetails, string $url, $result = NULL)
    {
        foreach($folderContentDetails as $key => $item)
        {
            if($url === $item->url)
            {
                return $item;
            }
    
            if("folder" === $item->elementType)
            {
              return self::getPathForUrl($item->folderContent, $url, $result);
            }
        }
    }
    

    PS:记住 if/return 的最佳实践:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-27
      • 2012-03-11
      • 1970-01-01
      • 2012-10-16
      相关资源
      最近更新 更多