Reputation: 2994
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
Upvotes: 1
Views: 1445
Reputation: 158
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;
}
Upvotes: 1
Reputation: 26066
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
Upvotes: 1
Reputation: 2152
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.
Upvotes: 1