Clément Malet
Clément Malet

Reputation: 5090

Why does this for-loop comparison fail after auto-incrementing on letters

I just gave this answer : https://stackoverflow.com/a/25688064/2627459 in order to loop over letters combination, with the following code :

for ($letter = 'a'; ; ++$letter) {
  echo $letter . '<br>';
  if ($letter == 'zz') break;
}

Which is just working fine.

I then tried to move the break into the for loop comparison, feeling that it would be better :

for ($letter = 'a'; $letter < 'zz'; ++$letter) {
  echo $letter . '<br>';
}

But of course, the last value (zz) wasn't showing, so I tried :

for ($letter = 'a'; $letter < 'aaa'; ++$letter) {
  echo $letter . '<br>';
}

And I don't know why, but it's giving me the following output :

a

So I tried several entries, and the (weird) results are :

Entry : $letter < 'yz' - Output : Up to y only

Entry : $letter < 'zzz' - Output : Up to zzy

I don't get why it works when the chain starts with z, but it fails in any other case (letter).

Morover, in the case of $letter < 'aaa', it displays a, but not the next one. At worst, I would have expected it to fail with a < 'aaa' and so display nothing. But no.

So, where does this behavior come from, am I missing something on how PHP compare these values ?

(I'm not looking for a workaround, but for an explanation. By the way, if any explanation comes with a working code, it's perfect !)

Upvotes: 0

Views: 67

Answers (1)

Mark Baker
Mark Baker

Reputation: 212422

Comparison is alphabetic:

$letter < 'yz' 

When you get to y, you increment again and get z..... alphabetically, z is greater than yz

If you use

    $letter != 'yz' 

for your comparison instead, it will give you up to yy

So

for ($letter = 'a'; $letter !== 'aaa'; ++$letter) {
    echo $letter . '<br>';
}

will give from a, through z, aa, ab.... az, ba.... through to zz.

See also this answer and related comments

EDIT

Personally I like incrementing the endpoint, so

$start = 'A';
$end = 'XFD';

$end++;
for ($char = $start; $char !== $end; ++$char) {
    echo $char, PHP_EOL;
}

Upvotes: 4

Related Questions