siddesh savant
siddesh savant

Reputation: 81

Convert a numeric string with no delimiters into an array of potentially multi-digit numbers

How can I split a string with no delimiters, for example $a = '89111213';, into an array of integers?

Desired result:

[8, 9, 11, 12, 13]

I generate that input number in a loop with concatenation like $a .= $somevariable;.

Upvotes: -4

Views: 133

Answers (5)

mickmackusa
mickmackusa

Reputation: 48071

This is an XY Problem that you shouldn't need to solve. Simply don't use concatenation to build the input string in the first place. Change your syntax to push elements into a flat array:

$result = [];
foreach ($somevariables as $somevariable) {
    $result[] = $somevariable;
}
var_export($result);

In an alternate universe where your coding requirement is legitimate, I've got a couple of solutions which will endeavor to split the string into an array of increasing values (assuming the data accommodates such splitting).

Functional style: (Demo)

$str = '89111213';

var_export(
    array_reduce(
        str_split($str),
        function ($result, $digit) {
            if (count($result) > 1 && strnatcmp(...array_slice($result, -2)) > 0) {
                $result[array_key_last($result)] .= $digit;
            } else {
                $result[] = $digit;
            }
            return $result;
        },
        []
    )
);

Using references: (Demo)

$str = '89111213';

$result = [];
$last = '';
$secondLast = '';
foreach (str_split($str) as $digit) {
    if (($secondLast <=> $last) === 1) {
        $last .= $digit;
    } else {
        $secondLast =& $last;
        unset($last);
        $last = $digit;
        $result[] =& $last;
    }
}
var_export($result);

Upvotes: 1

Felix Kling
Felix Kling

Reputation: 817208

Update:

As @therefromhere suggests in his comment, instead of concatenating the numbers into one string,put them in an array directly:

$a = array();

for(...) {
    $a[] = $somevariable;

}

Here is something that works in a way.

Important:
Assumption: Numbers are concatenated in increasing order and start with a number < 10 :)

$str = "89111213";
$numbers = array();
$last = 0;
$n = '';
for($i = 0, $l = strlen($str);$i<$l;$i++) {
    $n .= $str[$i];
    if($n > $last || ($i == $l - 1)) {
        $numbers[] = (int) $n;
        $last = $n;
        $n = '';
    }
}

print_r($numbers);

prints

Array
(
    [0] => 8
    [1] => 9
    [2] => 11
    [3] => 12
    [4] => 13
)

Although this might work to some extend, it will fail in a lot of cases. Therefore:

How do you obtain 89111213 ? If you are generating it from the numbers 8,9,11, etc. you should generate something like 8,9,11,12,13.

Upvotes: 2

Emil Vikstr&#246;m
Emil Vikstr&#246;m

Reputation: 91983

This looks dangerous. Have you concatenated several numbers to one integer? Note that there's an upper limit on integer values so you may experience bugs with many elements.

Also note that your problem is not possible to solve correctly when the numbers have different lengths, because you cannot know which of these combinations (if any) is correct for 89111213:

  • 8, 9, 11, 12, 13
  • 89, 111, 213
  • 8, 9, 11, 1213
  • 8, 91, 11213

You will need some sort of separator to make it stable and future proof.

Upvotes: 2

You can use explode():

$b = explode(' ', $a);

Upvotes: 2

Ryan Bigg
Ryan Bigg

Reputation: 107738

<? explode(" ", "a b c d e") ?>

Upvotes: 1

Related Questions