2015-07-22 2 views
0

Добрый день. У меня есть функция парсер, что берущий массив строки, как это:PHP рекурсивная функция уровня гнездования достигнута

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

И recursivelly поднимает уровень тех, кто начинает с Астерикса, чтобы получить эту

['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 »достигнут, прерывая!» ошибка.

Я знаю, что это имеет какое-то отношение к бесконечной рекурсии, но я не могу отслеживать то место, где оно происходит, и это странно.

+0

Если у вас есть '['* a', 'b', '* c']', то должно быть '['b', ['a', 'c']]' или '[ ['a'], 'b', ['c']] '? – kainaw

+0

Я думаю, [[a], b, [c]], потому что астры показывают уровень. Я ошибаюсь? – splash58

+0

@ splash58 Это похоже на то, что он пытается сделать, но если он хочет '['b', ['a', 'c']]', это было бы намного проще. Ошибка, очевидно, вызвана изменением $ ARRAY внутри foreach на основе $ ARRAY при одновременном увеличении $ i без учета $ ARRAY. – kainaw

ответ

2

Обычно я не переписываю код, но ваш код можно уменьшить и упростить, пока, из того, что я вижу, получаю желаемый результат. Смотрите, если это работает для вас:

$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; 
} 

Обратите внимание, что это не возможно для массива $ [$ я], чтобы быть массивом, так что проверка будет удален. Рекурсия выполняется в массиве temp, создаваемом при обнаружении *. $ I ближе привязан к $ массиву, чтобы восстановить его после разбора серии * элементов.

+0

Прохладный. это правильно (если я правильно понимаю) работает с [a, **** b, * c, d] – splash58

+0

Я только что проверил, чтобы проверить. Он работает с '['a', '****** b', '* c', 'd']' – kainaw

+0

Wow thanks. это поистине замечательная перепись. Но почему моя функция не работала? Я имею в виду $ ARRAY [$ i] = recursive_array_parser ($ ARRAY [$ i]); должен взять массив, работать с ним и вернуть его вместо старой части. Я не понимаю, почему это должно быть связано с моей функцией. –

0

Вот мое решение. Нет вложенных циклов.

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; 
} 
Смежные вопросы