1

I am learning php and wanted to try out recursion. I have made a function which gets a word and if its' length is over 30 characters it divides it into halves. And I have made a recursion, so if one of a halves is over 30 words, it divides it as well and so on.

function breakLongWords($val) {
    $array = explode(" ", $val);

    foreach ($array as $key => $word) {
        if (strlen($word) > 30) {

            for ($i = strlen($word) + 1; $i >= round(strlen($word)/2); $i--) {
                $word[$i+1] = $word[$i];
                if ($i == round(strlen($word)/2)) {
                    $word[$i] = " ";
                }
            }

            breakLongWords($word); 
            $array[$key] = $word;
        }

        $result = implode(" ", $array);
    }

    var_dump($result);
}

$str = "SuperDuperExtraGiggaDoubleTrippleSpicyWithCheeseLongUnlimitedString123";
breakLongWords($str);

I am testing it out in repl.it with var_dump function. Somehow last result is an entry word divided into two halves instead of four (70 characters). However one of the "var_dumps" prints correct result.

string(37) "SuperDuperExtraGigg aDoubleTrippleSpi"
string(35) "cyWithCheeseLongUn limitedString123"
string(73) "SuperDuperExtraGigg aDoubleTrippleSpi cyWithCheeseLongUn limitedString123"
string(71) "SuperDuperExtraGiggaDoubleTrippleSpi cyWithCheeseLongUnlimitedString123"

Could you help me please solve this issue?

https://repl.it/repls/SeveralBountifulCub

2 Answers2

0

Ok, I have solved it myself.

function breakLongWords($val) {
    $array = explode(" ", $val);

    foreach ($array as $key => $word) {
        if (strlen($word) > 30) {

            for ($i = strlen($word) + 1; $i >= round(strlen($word)/2); $i--) {
                $word[$i+1] = $word[$i];
                if ($i == round(strlen($word)/2)) {
                    $word[$i] = " ";
                }
            }

            $array[$key] = breakLongWords($word);
        }

        $result = implode(" ", $array);
    }

    return $result;
}

$str = "SuperDuperExtraGiggaDoubleTrippleSpicyWithCheeseLongUnlimitedString123SuperDuperExtraGiggaDoubleTrippleSpicyWithCheeseLongUnlimitedString123";

echo breakLongWords($str);

The result looks like this

SuperDuperExtraGiggaDoubl eTrippleSpicyWithCheese LongUnlimitedString123Su perDuperExtraGiggaDoubl eTrippleSpicyWithCheese LongUnlimitedString123
0

I think it is not a good approach to mix the two conditions (break words and break a long word). Therefor use 2 methods instead:

function breakLongWord($str, $arr = [], $limit = 30) {
    $arr[] = substr($str, 0, $limit);
    $rest = substr($str, $limit);
    if (strlen($rest)) {
        $arr = breakLongWord($rest, $arr);
    }
    return $arr;
}
function breakLongWords($str) {
    $words = explode(" ", $str);
    $arr = [];
    foreach ($words as $word) {
        $arr[] = breakLongWord($word);
    }
    return $arr;
}

Both methods will return an array, which you can easy turn into strings by using the implode().

Using the method breakLongWord with the string:

SuperDuperExtraGiggaDoubleTrippleSpiSuperDuperExtraGiggaDoubleTrippleSpi

will return the array (output with var_dump()):

array (size=3)
  0 => string 'SuperDuperExtraGiggaDoubleTrip' (length=30)
  1 => string 'pleSpiSuperDuperExtraGiggaDoub' (length=30)
  2 => string 'leTrippleSpi' (length=12)

Using the method breakLongWords with the string:

 SuperDuperExtraGiggaDoubleTrippleSpi1SuperDuperExtraGiggaDoubleTrippleSpi2 SuperDuperExtraGiggaDoubleTrippleSpi1SuperDuperExtraGiggaDoubleTrippleSpi2 testtesttest1234567890

Will produce following array (output with var_dump()):

array (size=3)
  0 => 
    array (size=3)
      0 => string 'SuperDuperExtraGiggaDoubleTrip' (length=30)
      1 => string 'pleSpi1SuperDuperExtraGiggaDou' (length=30)
      2 => string 'bleTrippleSpi2' (length=14)
  1 => 
    array (size=3)
      0 => string 'SuperDuperExtraGiggaDoubleTrip' (length=30)
      1 => string 'pleSpi1SuperDuperExtraGiggaDou' (length=30)
      2 => string 'bleTrippleSpi2' (length=14)
  2 => 
    array (size=1)
      0 => string 'testtesttest1234567890' (length=22)

But.. To cut a long story short: For this problem you could use str_split() (src)

1stthomas
  • 731
  • 2
  • 15
  • 22