【问题标题】:turning this trainwreck of a function into a recursive one将这个函数的残骸变成递归函数
【发布时间】:2013-07-15 17:02:52
【问题描述】:

我现在大部分时间都在尝试构建这个递归函数,但我似乎无法让它按照我想要的方式工作。

首先,我有一个属性,其中包含函数必须访问的一些数据:

$this->data

然后我有了这个字符串,它的目的是变成一个相对路径:

$path = 'path.to.%id%-%folder%.containing.%info%';

字符串中像这样的部分:%value% 将加载在$this->data property 中找到的一些动态值(像这样:$this->data['id'];$this->data['folder'];

为了让事情变得真正有趣,该属性可以再次引用自己,如下所示:$this->data['folder'] = 'foldername.%subfolder%'; 并且还有两个 %values% 由 - 分隔,必须单独放置。

所以对于这个问题,我一直在尝试创建一个递归函数,该函数将从 data 属性中加载动态值,如果新值包含另一个 %value% 则再次加载,依此类推,直到不再有 %value%已加载。

到目前为止,这是我能想到的:

    public function recursiveFolder( $folder, $pathArr = null )
    {
        $newPathArr = explode( '.', $folder );
        if ( count ( $newPathArr ) !== 1 )
        {
            foreach( $newPathArr as $id => $folder )
            {
                $value = $this->recursiveFolder( $folder, $newPathArr );
                $resultArr = explode( '.', $value );
                if ( count ( $resultArr ) !== 1 )
                {
                    foreach ( $resultArr as $nid => $result )
                    {
                        $nvalue = $this->recursiveFolder( $result, $newPathArr );
                        $resultArr[$nid] = $nvalue;
                    }

                }
                $resultArr = implode( '.',$resultArr );
                $newPathArr[$id] = $resultArr;
            }
        }
        else
        {
            $pattern = '/%(.*?)%/si';
            preg_match_all( $pattern, $folder, $matches );
            if ( empty( $matches[0] ) )
            {
                return $folder;
            }
            foreach ( $matches[1] as $mid => $match )
            {
                if ( isset( $this->data[$match] ) && $this->data[$match] != '' )
                {
                    $folder = str_replace( $matches[0][$mid], $this->data[$match], $folder );
                    return $folder;
                }
            }
        }

        return $newPathArr;
    }

不幸的是,它根本不是一个递归函数,因为当它具有多层 %values% 时它会停止运行,但几乎可以使用两层。 (我只是对其进行了编码,以便在这一点上它可以在极简的水平上工作)。

它的工作原理如下:

它应该转向:

'files.%folder%.blog-%type%.and.%time%'

进入:

'files.foldername.blog-post.and.2013.feb-12th.09'

基于此:

$data['folder'] = 'foldername';
$data['type']   = 'post';
$data['time']   = '%year%.%month%-%day%';
$data['year']   = 2013;
$data['month']  = 'feb';
$data['day']    = '12th.%hour%';
$data['hour']   = '09';

希望您能提供帮助! 周杰伦

【问题讨论】:

    标签: php function methods


    【解决方案1】:

    我不认为需要递归地解决这个问题:

    <?php
    function putData($str, $data)
    {
        // Repeat the replacing process until no more matches are found:
        while (preg_match("/%(.*?)%/si", $str, $matches))
        {
            // Use $matches to make your replaces
        }
        return $str;
    }
    ?>
    

    【讨论】:

    • 也许可以,但是如果将值替换为包含另一个 %% 的新值,情况会怎样?比如 %time% 会变成 %year%.%month%-%day% ,它又会变成:2013.feb-12th.%hour% ,最终会变成:2013.feb-12th.09。 (使用我问题底部的示例)。这就是我要使用递归函数的原因,但这是漫长的一天,我可能会遗漏一些东西。
    • 我的方法首先%time% 会变成%year%.%month%-%day%,然后preg_match("/%(.*?)%/si", $str, $matches) 会是真的,因为有新的值要被替换,所以它会再次执行循环。这种情况一直持续到所有 %thing% 被替换为止。
    • 确实很有魅力!过火我不觉得很傻吗!非常感谢您的解决方案!
    猜你喜欢
    • 1970-01-01
    • 2019-03-01
    • 2012-12-30
    • 2011-10-26
    • 2015-06-27
    • 1970-01-01
    • 2016-08-08
    • 1970-01-01
    • 2018-05-31
    相关资源
    最近更新 更多