2

I need to convert a string into a set of arrays of a fixed length.

Example: input: 1111122222333333

I need output of

[0] =>
    [0] => 1
    [1] => 1
    [2] => 1
    [3] => 1
    [4] => 1
[1] =>
    [0] => 2
    [1] => 2
    [2] => 2
    [3] => 2
    [4] => 2

The following code works great:

    for ($x = 0; $x < count($codedDataArray) - $colWidthSum + 1; $x += $colWidthSum + 1) {

        for ($c = 0; $c <= $colWidthSum; $c++) {
            $rows[$j][] = $codedDataArray[$z];
            $z++;
        }
        $j++;
    }

but it runs out of memory when I give it really large strings, say 10959 bytes.

Is there a built-in PHP function I'm missing that will do the same thing, or am I just going to have to deal with the memory issues?

EDIT 1: I'm running out of memory on both preg_split and str_split as well, so I'm probably doing something really wrong. I'll still mark as answered, as soon as I figure out what my initial issue was in the first place.

EDIT 2: The string length is actually 745,982 bytes, I was looking at the compressed length.

EDIT 3: I think the string is just too big. I'll have to see if there as a way of breaking it up without losing data since that's actually a small example and it's actually binary data. Thanks for the answers everyone!

3
  • Runs out of memory or infinite loop? Commented Jun 20, 2011 at 17:32
  • runs out of memory. Works find on a stream of length 137, so I don't think it's a loop. Commented Jun 20, 2011 at 17:35
  • Doesn't seem like it should with a 11k string... Commented Jun 20, 2011 at 17:38

5 Answers 5

14

Try this. I've just tested with a string of 10,000 words and it didn't run out of memory:

$array = str_split($string);

// returns $array = Array
(
    [0] => 1
    [1] => 1
    [2] => 1
    [3] => 1
    [4] => 1
    [5] => 2
    [6] => 2
    [7] => 2
    [8] => 2
    [9] => 2
    [10] => 3
    [11] => 3
   // and so on
)

Then:

array_chunk($array, 5);

// returns:

[0] => Array
    (
        [0] => 1
        [1] => 1
        [2] => 1
        [3] => 1
        [4] => 1
    )

[1] => Array
  (
        [0] => 1
        [1] => 2
        [2] => 2
        [3] => 2
        [4] => 2
    )
Sign up to request clarification or add additional context in comments.

Comments

3

The str_split function might help you, but you'll have to handle the last chunk yourself.

2 Comments

That looked promising, but that runs out of memory as well.
To be more specific, your sample output needs two splits, you can get it with something like array_map ('str_split', str_split ($str, $length)). If if runs out of memory, then you may want to raise your PHP "max_memory" limit setting.
1

You're not missing something, this is not something built-in. PHP is great at parsing strings, but it can have difficulties with large inputs.

If you know the length of the chunks (and it looks like you do):

// Breaks the strink into $chunkLength sized pieces.
$arr = str_split($input, $chunkLenght);
// str_split all of the chunks:
// explode technically is more historic, but str_split is easier.
array_walk($arr, 'str_split');

If you don't know the chunk size, you'll need to figure that out:

$sizes = array();
$current = FALSE;
$len = count($input);
$curCount = 0;

for($i = 0; $ < $len; $i++){
    if($current != $input[$i]) {
        $current = $input[$i];
        $sizes[$current] = $curCount;
        $curCount = 0;
    }
    $curCount++;
}

function get_filled_array($num, $count) {
     return arrat_pad(array(), $count, $num);
}
$output = array();

foreach($sizes as $index => $count) {
    $output[$index] = get_filled_array($index, $count);
}

Comments

1

Use something like

$str = '1111122222333333';
$result = array_chunk(str_split($str), 5);
print_r($result);

Anyways, one way to handle out-of-memory errors can be the creation of a php script that only imlements your internal "for loop" and then call an PHP exec inside the biggest loop.

This will cause the process to launch a thread for each "looping job" without overflowing the memory

2 Comments

I think I may have to go the php exec route unless I can figure out what is causing the modem issues. I could expand the max memory, but that just means I'm willing to accept I have poor code.
This is a poor use of preg_split() as you don't need the regular expression. str_split() does the same thing in this case and would be better performing. It was already suggested by Damien Pirsy.
0

Push substrings to the array

$result = array();
for ($index=0; $index<=strlen($string)-$width; $index+= $width)
{
array_push($result,substr($string,$index,$width));
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.