Frage

I am looking to increment strings in php where after z the next increment is numeric.

a..aa..ab..az..a0

I have tried the following and several other attempts, any ideas or suggestions are greatly appreciated.

<?php

$start = 'a';
$end = '999';
while($start != $end)
{
    $start = ++$start;
    echo $start . "\n";
}

however the results look like this

a
b
...
aaaa

If I add a number to the end of $start like as follows

<?php

$start = 'a1';
$end = '999';
while($start != $end)
{
    $start = ++$start;
    echo $start . "\n";
}

The results look like this

a1
a2
...
aa1
...
az9
ba0

The results I am looking for should look like

a1
a2
...
aa1
...
az9
a00
a01
...
ba0
War es hilfreich?

Lösung

Well, the ++ is pretty strictly defined in what it does - increments characters by ASCII values, for a very limited range of characters, so your problem will most likely need a custom solution.

I tried:

$start = 'a';
$end = '999';
$seq = 'abcdefghijklmnopqrstuvwxyz0123456789';

while($start != $end)
{
    echo $start . "\n";

    $pass = 1;
    for ($i = strlen($start) - 1; $i >= 0; $i--) {
        if (!$pass) break;
        else $pass--;

        $last = substr($start, $i, 1);
        $pos = strpos($seq, $last);

        if ($pos == strlen($seq) - 1) {
            $pos = 0;
            $pass++;
        } else $pos++;
        $start[$i] = $seq[$pos]; 
    }
    if ($pass) $start .= substr($seq, 0, 1);
}

which, if you accept my comment, gets you the sequence you seem to want. All the code does is manually go through $start backwards, incrementing the character to the next one in $seq and, if it's the last one, set it to the first one and "carry the one". Really, it's just a character sum.

Andere Tipps

I would recommend using range() and a for loop instead. Here is my solution to the question as presented as I understand it. But looking over your question again & your desired output, still unclear if this will be a solution for you.

// First, generate an array consisting of the alhabet.
$alphabet = range('a','z');

// Now, set a min & a max number to increment.
$number_min = 0;
$number_max = 999;

// Now loop through the numbers via 'for' loop.
for ($count = $number_min; $count <= $number_max; $count++) {

  // And loop through the alphabet via a 'foreach' loop.
  foreach ($alphabet as $letter_key => $letter_value) {

    // Set an append value if the '$count' value is greater than the '$number_min' value.
    $append_value = (($count > $number_min) ? $count : null);

    // Now echo the '$letter_value' and the '$append_value.'
    echo $letter_value . $append_value . '<br />';

  } // foreach

} // for

EDIT Here is another stab at the issue using a modulus operator. Doesn’t seem 100% like what you want, but believe this is closer?

// First, generate an array consisting of the alhabet.
$alphabet = range('a','z');

// Now, set a min & a max number to increment.
$number_min = 0;
$number_max = 999;

// Now loop through the numbers via 'for' loop.
for ($count = $number_min; $count <= $number_max; $count++) {

  // And loop through the alphabet via a 'foreach' loop.
  foreach ($alphabet as $letter_key => $letter_value) {

    // Set null values for the append variables.
    $numerical_append = $alphabet_append = null;

    if ($count > $number_min) {

      // Set a numerical append value if the '$count' value is greater than the '$number_min' value.
      $numerical_append = $count;

      // Get the alphabet key based on the '$count' & loop it via a modulous of the size of the '$alphabet' array.
      $alphabet_key = ($count % (count($alphabet)+1)) - 1;

      // Set an alphabetical append value if the '$count' value is greater than the '$number_min' value.
      $alphabet_append = $alphabet[$alphabet_key];
    }

    // Now echo the '$letter_value' and the '$numerical_append.'
    echo $letter_value . $alphabet_append . $numerical_append . '<br />';

  } // foreach

} // for

Why not using base_convert?

Passing from base 10 to 36 (maximum of base_convert) you will have what you want.

The sequence will be this: 0123456789abcdefghijklmnopqrstuvwxyz

Which is not like in the answer of #Naltharial but it seems to me this is what you want.

For example:

    $var = base_convert('az9',36,10);
    echo base_convert($var,10,36).PHP_EOL; $var+=1;
    echo base_convert($var,10,36).PHP_EOL; $var+=1;
    echo base_convert($var,10,36).PHP_EOL.PHP_EOL; $var+=1;

    $var = base_convert('azz',36,10);
    echo base_convert($var,10,36).PHP_EOL; $var+=1;
    echo base_convert($var,10,36).PHP_EOL; $var+=1;
    echo base_convert($var,10,36).PHP_EOL; $var+=1;

Will print:

    az9
    aza
    azb

    azz
    b00
    b01

As you really want the sequence to be : abcdefghijklmnopqrstuvwxyz0123456789

You can then do :

    // $string is the string in base36
    $length = strlen($string);
    $result = '';
    $base36  = '0123456789abcdefghijklmnopqrstuvwxyz';
    $ownBase = 'abcdefghijklmnopqrstuvwxyz0123456789';
    for ($i=0; $i<$length; $i++) {
        $result .= $ownBase[strpos($string[$i],$base36)];
    }

Your function can then be :

    // Set a min & a max number to increment.
    $number_min = '0';
    $number_max = '999';
    // Transform in number
    $length     = strlen($number_max);
    $result     = '';
    $base36     = '0123456789abcdefghijklmnopqrstuvwxyz';
    $ownBase    = 'abcdefghijklmnopqrstuvwxyz0123456789';
    for ($i=0; $i<$length; $i++) {
        $result .= $base36[strpos($number_max[$i],$ownBase)];
    }
    $length     = strlen($number_min);
    // Number max in base 10 to reach
    $nbLoop     = base_convert($result,36,10);
    for ($i=0; $i<$length; $i++) {
        $result .= $base36[strpos($number_min[$i],$ownBase)];
    }
    // Number min in base 10 to reach
    $nbLoop    -= base_convert($result,36,10);
    // Printing every number :
    for ($i=base_convert($result,36,10); $i<$nbLoop; $i++) {
      $string = base_convert($i,10,36);
      $length = strlen($string);
      $result = '';
      for ($j=0; $j<$length; $j++) {
          $result .= $ownBase[strpos($string[$j],$base36)];
      }
      echo $result;
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top