【问题标题】:PHP recursive function nesting level reached达到 PHP 递归函数嵌套级别
【发布时间】:2015-07-22 23:57:34
【问题描述】:

美好的一天。我有一个 parcer 函数,它接受一个这样的字符串数组:

['str','str2','str2','*str','*str2','**str2','str','str2','str2']

并且递归地提升那些以 asterix 开头的人的水平来获得这个

['str','str2','str2',['str','str2',['str2']],'str','str2','str2']

而功能是:

function recursive_array_parser($ARRAY) {
    do {

        $i = 0;
        $s = null;
        $e = null;
        $err = false;

        foreach ($ARRAY as $item) {

            if (!is_array($item)) { //if element is not array
                $item = trim($item);
                if ($item[0] === '*' && $s == null && $e == null) { //we get it's start and end if it has asterix
                    $s = $i;
                    $e = $i;
                } elseif ($item[0] === '*' && $e != null)
                    $e = $i;
                elseif (!isset($ARRAY[$i + 1]) || $s != null && $e != null) { //if there are no elements or asterix element ended we elevate it
                    $e = $e == NULL ? $i : $e;
                    $head = array_slice($ARRAY, 0, $s);
                    $_x = [];
                    $inner = array_slice($ARRAY, $s, $e - $s + 1);
                    foreach ($inner as $_i)
                        $_x[] = substr($_i, 1);

                    $inner = [$_x];
                    $tail = array_slice($ARRAY, $e + 1, 999) or [];
                    $X = array_merge($head, $inner);
                    $ARRAY = array_merge($X, $tail);

                    $s = null;
                    $e = null;
                    $err = true;
                }
            } else {
                $ARRAY[$i] = recursive_array_parser($ARRAY[$i]); //if the item is array of items we recur.
            }
            $i++;

            if ($err == true) {
                break 1;
            }
        }
    } while ($err);
    return $ARRAY;
}

当此函数运行时,我收到“致命错误:已达到 '200' 的最大函数嵌套级别,正在中止!”错误。

我知道它与无限递归有关,但我无法跟踪它发生的特定位置,这很奇怪。

【问题讨论】:

  • 如果你有['*a', 'b', '*c'],应该变成['b', ['a','c']]还是[['a'], 'b', ['c']]
  • 我认为 [[a],b,[c]] 因为星号显示水平。我错了吗?
  • @splash58 这似乎是他想要做的,但如果他想要['b', ['a', 'c']],这会简单得多。该错误显然是由基于 $ARRAY 在 foreach 中更改 $ARRAY 而在不考虑 $ARRAY 本身的情况下增加 $i 引起的。
  • @kainaw 听到作者的声音会更好:))
  • @splash58 [['a'], 'b', ['c']]

标签: php recursion


【解决方案1】:

我通常不会重写代码,但您的代码可以减少和简化,同时,据我所知,可以获得所需的结果。看看这是否适合你:

$a = array('a','b','c','*d','*e','**f','g','*h');
print_r($a);
$a = recursive_array_parser($a);
print_r($a);
function recursive_array_parser($array)
{
    $ret = array();
    for($i=0; $i<sizeof($array); $i++)
    {
        if($array[$i]{0}!='*') $ret[] = $array[$i];
        else
        {
            $tmp = array();
            for($j=$i; $j<sizeof($array) && $array[$j]{0}=='*'; $j++)
            {
                $tmp[] = substr($array[$j],1);
            }
            $ret[] = recursive_array_parser($tmp);
            $i = $j-1;
        }
    }
    return $ret;
}

请注意,$array[$i] 不可能是数组,因此删除了检查。递归发生在找到 * 时创建的临时数组上。 $i 更紧密地绑定到 $array 以在解析一系列 * 元素后正确重置它。

【讨论】:

  • 酷。它正确(如果我理解正确的话)适用于 [a,****b, *c, d]
  • 我刚刚检查以验证。它确实适用于['a', '******b', '*c', 'd']
  • 哇,谢谢。这是一个真正伟大的重写。但为什么我的功能不起作用?我的意思是 $ARRAY[$i] = recursive_array_parser($ARRAY[$i]);应该接受一个数组,使用它,并返回它来代替旧的部分。我不明白为什么它会影响我的功能。
  • @НиколайКахневич 我没有运行你的函数来分析它。看看它,它用一个数组替换了一个 * 项的实例,但不是全部。因此,[a, *b, *c] 变为 [a, [b, c], *c]。看看它是如何替换 *b 的,但它不会删除 *c。这就是我使用临时数组而不是就地替换的原因。
【解决方案2】:

这是我的解决方案。没有嵌套循环。

function recursive_array_parser($arr) {
    $out = array();
    $sub = null;
    foreach($arr as $item) {
        if($item[0] == '*') { // We've hit a special item!
            if(!is_array($sub)) { // We're not currently accumulating a sub-array, let's make one!
                $sub = array();
            }
            $sub[] = substr($item, 1); // Add it to the sub-array without the '*'
        } else {
            if(is_array($sub)) { 
                // Whoops, we have an active subarray, but this thing didn't start with '*'. End that sub-array
                $out[] = recursive_array_parser($sub);
                $sub = null;
            }
            // Take the item
            $out[] = $item;
        }
    }

    if(is_array($sub)) { // We ended in an active sub-array. Add it.
        $out[] = recursive_array_parser($sub);
        $sub = null;
    }

    return $out;
}

【讨论】:

    猜你喜欢
    • 2020-09-07
    • 2020-06-12
    • 2015-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-06
    • 1970-01-01
    • 2013-07-03
    相关资源
    最近更新 更多