This is a discussion on foreach nested loop problem: comparing array members to themselves within the alt.comp.lang.php forums, part of the PHP Programming Forums category; This is part of the core of a time scheduler. The idea is to compare a worker's prospective job ...
|
|||||||
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
|
|||
|
This is part of the core of a time scheduler.
The idea is to compare a worker's prospective job commitments to each other to see if they conflict. Some jobs are 'nonconflicting' so they should not be included in the comparisons. The script that uses nested foreach loops to compare 3 array members held in a single array to each other. Each member has a "pjJobID" key of 1, 2, or 3 and a "pjNonConflicting" key of 1 or 0 With just the 2 nested loops (no comparisons at all), the inner loop processes 9 times; all members are combined 3^2 in all ways, as expected. If the pjJobID comparison is added to the inner loop, to prevent members from being compared to themselves, the inner loop only processes 6 times, not 9 times. 1,1 2,2 and 3,3 are caught as expected 2,1 3,1 and 3,2 are processed and pass the comparison 1,2 1,3 and 2,3 do not appear to get processed. Why? If the pjNonConflicting comparison is added to the inner loop, to prevent members from being compared to nonconflicting jobs, the inner loop only processes 3 times, not 9 times, and *no* members pass the comparisons. 1,1 gets kicked by the pjJobID comparison 2,1 and 3,1 get kicked by the pjNonConflicting comparison Nothing else appears to get processed! What about 3,2 or 2,3 ? They should pass, shouldn't they? And shouldn't the other 6 combinations have gotten processed in some way? I've been messing with this thing all night and reading the php man pages but I can't figure this out. I had the comparison conditions combined in one 'if' statement but separated them to eliminate the possibility that the weirdness is due to short circuiting in the comparison in some way. Does this have to do with the array pointers and the break statement or is it something about the foreach or arrays that I don't understand? I'm using php 4.2.3 if that matters...I won't even mention 'bug' because historically it's always a misunderstanding on my part. Here's the code, it's really simple, I just included some descriptive printout statements: <?php $ProspectiveJobs[0]["pjJobID"] ="1"; $ProspectiveJobs[0]["pjNonConflicting"] ="1"; $ProspectiveJobs[1]["pjJobID"] ="2"; $ProspectiveJobs[1]["pjNonConflicting"] ="0"; $ProspectiveJobs[2]["pjJobID"] ="3"; $ProspectiveJobs[2]["pjNonConflicting"] ="0"; foreach($ProspectiveJobs as $PJ1) { foreach($ProspectiveJobs as $PJ2) { if (($PJ1["pjJobID"]==$PJ2["pjJobID"])) { echo "<pre>\n kicked out 1 \n "; print_r($PJ1); print_r($PJ2); echo "\n ###################### \n</pre>"; break; } if (($PJ1["pjNonConflicting"]=="1") ||($PJ2["pjNonConflicting"]=="1")) { echo "<pre>\n kicked out 2 \n "; print_r($PJ1); print_r($PJ2); echo "\n ###################### \n</pre>"; break; } echo " <pre>\n passed \n"; print_r($PJ1); print_r($PJ2); echo "\n ###################### \n</pre>"; } } ?> Thanks for any light on this weirdness, r |
|
|||
|
r wrote:
> This is part of the core of a time scheduler. > The idea is to compare a worker's prospective job commitments to each other > to see if they conflict. Some jobs are 'nonconflicting' so they should not > be included in the comparisons. > > The script that uses nested foreach loops to compare 3 array members held in > a single array to each other. > Each member has a "pjJobID" key of 1, 2, or 3 and a "pjNonConflicting" key > of 1 or 0 > With just the 2 nested loops (no comparisons at all), the inner loop > processes 9 times; all members are combined 3^2 in all ways, as expected. > > If the pjJobID comparison is added to the inner loop, to prevent members > from being compared to themselves, the inner loop only processes 6 times, > not 9 times. > > 1,1 2,2 and 3,3 are caught as expected > > 2,1 3,1 and 3,2 are processed and pass the comparison > > 1,2 1,3 and 2,3 do not appear to get processed. Why? > > If the pjNonConflicting comparison is added to the inner loop, to prevent > members from being compared to nonconflicting jobs, the inner loop only > processes 3 times, not 9 times, and *no* members pass the comparisons. > > 1,1 gets kicked by the pjJobID comparison > 2,1 and 3,1 get kicked by the pjNonConflicting comparison > Nothing else appears to get processed! > > > What about 3,2 or 2,3 ? They should pass, shouldn't they? And shouldn't > the other 6 combinations have gotten processed in some way? > > I've been messing with this thing all night and reading the php man pages > but I can't figure this out. > I had the comparison conditions combined in one 'if' statement but separated > them to eliminate the possibility that the weirdness is due to short > circuiting in the comparison in some way. > > Does this have to do with the array pointers and the break statement or is > it something about the foreach or arrays that I don't understand? > I'm using php 4.2.3 if that matters...I won't even mention 'bug' because > historically it's always a misunderstanding on my part. > > > Here's the code, it's really simple, I just included some descriptive > printout statements: > > > <?php > $ProspectiveJobs[0]["pjJobID"] ="1"; > $ProspectiveJobs[0]["pjNonConflicting"] ="1"; > > $ProspectiveJobs[1]["pjJobID"] ="2"; > $ProspectiveJobs[1]["pjNonConflicting"] ="0"; > > $ProspectiveJobs[2]["pjJobID"] ="3"; > $ProspectiveJobs[2]["pjNonConflicting"] ="0"; > > foreach($ProspectiveJobs as $PJ1) > { > foreach($ProspectiveJobs as $PJ2) > { > if (($PJ1["pjJobID"]==$PJ2["pjJobID"])) > { > echo "<pre>\n kicked out 1 \n "; > print_r($PJ1); > print_r($PJ2); > echo "\n ###################### \n</pre>"; > break; > } > if (($PJ1["pjNonConflicting"]=="1") > ||($PJ2["pjNonConflicting"]=="1")) > { > echo "<pre>\n kicked out 2 \n "; > print_r($PJ1); > print_r($PJ2); > echo "\n ###################### \n</pre>"; > break; > } > > echo " <pre>\n passed \n"; > print_r($PJ1); > print_r($PJ2); > echo "\n ###################### \n</pre>"; > > } > > } > ?> > > Thanks for any light on this weirdness, > r > > can the two if statement be combined? In the end either one is a fail, so if you OR both of them together and have the passed logic as the else, you don't need the break; <?php $ProspectiveJobs[0]["pjJobID"] ="1"; $ProspectiveJobs[0]["pjNonConflicting"] ="1"; $ProspectiveJobs[1]["pjJobID"] ="2"; $ProspectiveJobs[1]["pjNonConflicting"] ="0"; $ProspectiveJobs[2]["pjJobID"] ="3"; $ProspectiveJobs[2]["pjNonConflicting"] ="0"; foreach($ProspectiveJobs as $PJ1) { foreach($ProspectiveJobs as $PJ2) { if (($PJ1["pjJobID"]==$PJ2["pjJobID"]) || (($PJ1["pjNonConflicting"]=="1") ||($PJ2["pjNonConflicting"]=="1"))) { echo "<pre>\n kicked out \n "; print_r($PJ1); print_r($PJ2); echo "\n ###################### \n</pre>"; } else { echo " <pre>\n passed \n"; print_r($PJ1); print_r($PJ2); echo "\n ###################### \n</pre>"; } } } ?> |
|
|||
|
Yes, thanks. I used if else instead of break and the code works better.
I'm still wondering what was happening with the break. Any ideas? r "John" <noone@nowhere.com> wrote in message news:cud4qu$b12$1@austar-news.austar.net.au... >r wrote: >> This is part of the core of a time scheduler. >> The idea is to compare a worker's prospective job commitments to each >> other to see if they conflict. Some jobs are 'nonconflicting' so they >> should not be included in the comparisons. >> >> The script that uses nested foreach loops to compare 3 array members held >> in a single array to each other. >> Each member has a "pjJobID" key of 1, 2, or 3 and a "pjNonConflicting" >> key of 1 or 0 >> With just the 2 nested loops (no comparisons at all), the inner loop >> processes 9 times; all members are combined 3^2 in all ways, as >> expected. >> >> If the pjJobID comparison is added to the inner loop, to prevent members >> from being compared to themselves, the inner loop only processes 6 times, >> not 9 times. >> >> 1,1 2,2 and 3,3 are caught as expected >> >> 2,1 3,1 and 3,2 are processed and pass the comparison >> >> 1,2 1,3 and 2,3 do not appear to get processed. Why? >> >> If the pjNonConflicting comparison is added to the inner loop, to prevent >> members from being compared to nonconflicting jobs, the inner loop only >> processes 3 times, not 9 times, and *no* members pass the comparisons. >> >> 1,1 gets kicked by the pjJobID comparison >> 2,1 and 3,1 get kicked by the pjNonConflicting comparison >> Nothing else appears to get processed! >> >> >> What about 3,2 or 2,3 ? They should pass, shouldn't they? And >> shouldn't the other 6 combinations have gotten processed in some way? >> >> I've been messing with this thing all night and reading the php man pages >> but I can't figure this out. >> I had the comparison conditions combined in one 'if' statement but >> separated them to eliminate the possibility that the weirdness is due to >> short circuiting in the comparison in some way. >> >> Does this have to do with the array pointers and the break statement or >> is it something about the foreach or arrays that I don't understand? >> I'm using php 4.2.3 if that matters...I won't even mention 'bug' because >> historically it's always a misunderstanding on my part. >> >> >> Here's the code, it's really simple, I just included some descriptive >> printout statements: >> >> >> <?php >> $ProspectiveJobs[0]["pjJobID"] ="1"; >> $ProspectiveJobs[0]["pjNonConflicting"] ="1"; >> >> $ProspectiveJobs[1]["pjJobID"] ="2"; >> $ProspectiveJobs[1]["pjNonConflicting"] ="0"; >> >> $ProspectiveJobs[2]["pjJobID"] ="3"; >> $ProspectiveJobs[2]["pjNonConflicting"] ="0"; >> >> foreach($ProspectiveJobs as $PJ1) >> { >> foreach($ProspectiveJobs as $PJ2) >> { >> if (($PJ1["pjJobID"]==$PJ2["pjJobID"])) >> { >> echo "<pre>\n kicked out 1 \n "; >> print_r($PJ1); >> print_r($PJ2); >> echo "\n ###################### \n</pre>"; >> break; >> } >> if (($PJ1["pjNonConflicting"]=="1") >> ||($PJ2["pjNonConflicting"]=="1")) >> { >> echo "<pre>\n kicked out 2 \n "; >> print_r($PJ1); >> print_r($PJ2); >> echo "\n ###################### \n</pre>"; >> break; >> } >> >> echo " <pre>\n passed \n"; >> print_r($PJ1); >> print_r($PJ2); >> echo "\n ###################### \n</pre>"; >> >> } >> >> } >> ?> >> >> Thanks for any light on this weirdness, >> r > can the two if statement be combined? In the end either one is a fail, so > if you OR both of them together and have the passed logic as the else, you > don't need the break; > > <?php > $ProspectiveJobs[0]["pjJobID"] ="1"; > $ProspectiveJobs[0]["pjNonConflicting"] ="1"; > > $ProspectiveJobs[1]["pjJobID"] ="2"; > $ProspectiveJobs[1]["pjNonConflicting"] ="0"; > > $ProspectiveJobs[2]["pjJobID"] ="3"; > $ProspectiveJobs[2]["pjNonConflicting"] ="0"; > > foreach($ProspectiveJobs as $PJ1) > { > foreach($ProspectiveJobs as $PJ2) > { > if (($PJ1["pjJobID"]==$PJ2["pjJobID"]) || > (($PJ1["pjNonConflicting"]=="1") ||($PJ2["pjNonConflicting"]=="1"))) > { > echo "<pre>\n kicked out \n "; > print_r($PJ1); > print_r($PJ2); > echo "\n ###################### \n</pre>"; > > } > else > { > echo " <pre>\n passed \n"; > print_r($PJ1); > print_r($PJ2); > echo "\n ###################### \n</pre>"; > } > } > > } > > > > ?> |