|
Posted by Osiris on 12/02/07 10:33
On Sun, 02 Dec 2007 00:53:06 +0000, Tim Roberts wrote:
> Osiris <et57@hotmail.com> wrote:
> .
>>Just something I would like to share:
>>
>>I just learned the hard way (2 days detective work on a bug) that foreach
>>loops are not at all like for loops, not intuitive at all. BEWARE: arrays
>>and matrices are sparse by design/definition in PHP.
>
> That's true, but I don't think that's the problem here.
>
>>I wish PHP would do array and matrix stuff like Fortran or C, btw.
>>Something for PHP 6 ?
>
> I doubt it. That's simply not its problem domain.
>
>>Check out this code:
>>
>>$k = array(1=>
>>array(1=>1,1,1,1,1,1),
>>array(2=>1,1,1,1,1),
>>array(3=>1,1,1,1),
>>array(4=>1,1,1),
>>array(5=>1,1),
>>array(6=>1));
>>
>>/* you would expect this to mirror the matrix about a diagonal from upper
>>left to lower right multiplying each coefficient by 2 on the way...
>>However, the foreach loop is tricky. */
>
> My guess is that it's not the foreach loop that is biting you, but rather
> the references.
>
>>foreach($k as $i=>& $_k)
>> foreach($_k as $j=>&$__k)
>> {
>> $__k *= 2;
>> if ($i != $j)
>> $k[$j][$i ] = $__k;
>> }
>
> What does this produce for you? Does the next-to-the-last line really do
> what you think? Is that making a copy of the value, or is it storing a
> reference to the value? That is, won't $k[2][1] simply be a reference to
> $k[1][2], and not a separate value?
>
this works ok, so the referencing is not the problem:
<?php
$f = array(1=>array(5=>1,3=>2,8=>3),array(3=>2,4,5));
foreach($f as &$_f)
foreach($_f as &$__f)
echo $__f." ";
for ($i=1; $i <= 6; $i++)
{
for ($j=1; $j <= 6; $j++)
echo $k[$i][$j]." ";
echo "<BR>";
}
?>
The thing is, that while mirroring a coefficient, it may be processed
again in a next iteration.
At the start of the routine, there is an upper triangular matrix, but
next, some elements of the lower triangle are added, having BEEN doubled.
foreach apparently does a
complete search for new elements each loop. Correct , but it's a very
different mechanism than a for loop, which pinpoints each element to
process
Now for the even more weird thing:
running the above loops in eclipse debugger, I get this:
2 4 4 4 4 4
4 2 4 4 4 4
4 4 2 4 4 4
4 4 4 2 4 4
4 4 4 4 2 4
4 4 4 4 4 2
Running it in Firefox on my localhost (apache 2), i get this:
2 2 2 2 2 2
2 1 1 1 1 1
2 2 1 1 1 1
2 2 2 1 1 1
2 2 2 2 1 1
2 2 2 2 2 1
[Back to original message]
|