0

I've had this problem a few times now when for looping over an array item.

In this instance I'm generating all 2 letter combinations of the alphabet.

The code works (and I know there's a much easier way of doing it with 2 for loops, but I'm trying something different).

However I have to do count -1 as count() returns the number 26 for the array length, however the 26th item obviously doesn't exist as it's 0 based?

Is there not a version of count() that works on a zero-based basis?

<?php
$alphas = range('a', 'z');

$alphacount = count($alphas);

// Why do I have to do this bit here?
$alphaminus = $alphacount -1;

$a = 0;
for ($i=0;$i<$alphacount;$i++)  {
    $first = $alphas[$a];
    $second = $alphas[$i];
    if ($i === $alphaminus && $a < $alphaminus  ) {
        $i = 0;
        $a ++;
    }
    echo "$first$second<br>";
}
?>

Without $alphaminus = $alphacount -1; I get undefined offset 26?

Alexander Wigmore
  • 3,157
  • 4
  • 38
  • 60
  • count is only 0 for an empty array, 1 element in an array gives count=1.... that's perfectly logical.... the array indexing is 0-based, not the count – Mark Baker Jun 01 '14 at 12:00

5 Answers5

2

How about:

<?php
$alphas = range('a', 'z');

$alphacount = count($alphas);

$a = 0;
for ($i=0;$i<$alphacount;$i++)  {
    $first = $alphas[$a];
    $second = $alphas[$i];
    if ($i >= $alphacount && $a < $alphaminus  ) {
        $i = 0;
        $a ++;
    }
    echo "$first$second<br>";
}

So you don't have to to -1 since you don't like it! :)

And how about:

$alphas = range('a', 'z');
for ($i = 0; $i < count($alphas); $i++) {
    for ($a = 0; $a < count($alphas); $a++) {
        echo "{$alphas[$i]}{$alphas[$a]}\n";
    }
}

Or forget about arrays! This is more fun :)

    array_walk($alphas, function ($a) use ($alphas) {
        array_walk($alphas, function ($b) use ($a) {
            print "$a$b\n";
        });
    });
ggioffreda
  • 650
  • 6
  • 11
2

The problem is that you reset $i to 0 in the loop; then on encountering the end of the loop $i is incremented, so the next run in the loop will be with $i = 1 instead of $i = 0.

That is, the next subrange of letters starts with (letter)b instead of (letter)a. (See your output: the next line after az is bb rather than ba.)

Solution: reset $i to -1 in the loop, then at the end it will run with the value 0 again.

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
1

You have 26 characters, but arrays in PHP are indexed from 0. So, indexes are 0, 1, ... 25.

pavel
  • 26,538
  • 10
  • 45
  • 61
1

count is 1-based and arrays created by range() are 0-based.

It means that:

$alphas[0] == a
$alphas[25] == z

$count($alphas) = 26; // there are 26 elements. First element is $alphas[0]
Patrick L.
  • 526
  • 6
  • 24
1

Why does it have to be so complicated? You could simply do

foreach ($alphas as $alpha)
{
    foreach($alphas as $alpha2)
    {
      echo $alpha.$alpha2."<br>";
    }
}

Note: It is mostly not a good idea to manipulate the loop counter variable inside the body of that very loop. You set $i to 0 on a certain condition. That could give you unexpected results, hence the reason why you have to navigate around it.

Hanky Panky
  • 46,730
  • 8
  • 72
  • 95
  • I know it's very simple to do it this way, I don't have a problem with the code, it's just a re-occurring problem I have with count() in general, when looping over arrays. – Alexander Wigmore Jun 01 '14 at 12:01
  • Ok can you please rephrase the question or provide another simpler example case so we can work on that confusion? – Hanky Panky Jun 01 '14 at 12:01