am working on php loops and i find myself that i need to write a nested loop bur when i try to combine foreach and for loop it yield to unexpected result
Here are my codes
foreach ($district_ward as $key => $value) {
$ward_ids = array_keys($district_ward[$key]);
echo $key;
for ($x = 0; $x < count($ward_ids)-1; $x++) {
$district_village[$key]= array_merge($value[$ward_ids[$x]], $value[$ward_ids[$x+1]]);
}
}
This gives me this
347
but when i print the value of $key within the for loop, that is
foreach ($district_ward as $key => $value) {
$ward_ids = array_keys($district_ward[$key]);
for ($x = 0; $x < count($ward_ids)-1; $x++) {
echo $key;
$district_village[$key]= array_merge($value[$ward_ids[$x]], $value[$ward_ids[$x+1]]);
}
}
i get this
3
I'm just going to guess that your 2nd and 3rd array are only one entry long. The condition for the loop specifies $x < count($ward_ids) - 1. If your array only has one entry, one - 1 will make it loop 0 times. In other words, your inner loop is not executed at all.
Are you printing this to a html page? Are your keys 3, 4 and 7? They would appear as 347 if you were echoing to an html page. Try
echo "$key<br />\n";
or even
echo "<pre>".print_r($district_ward)."</pre>";
before the loop to see what the array looks like.
foreach ($district_ward as $key => $value) {
$ward_ids = array_keys($district_ward[$key]);
for ($x = 0; $x < count($ward_ids); $x++) {
echo $key;
$district_village[$key]= array_merge($value[$ward_ids[$x]], $value[$ward_ids[$x+1]]);
}
}
Should do the trick, this because you start at 0 up UNTIL the amount of $ward_ids
Let's say your $ward_ids has 1 entry, then you would have looped 0 till 0, so no loops at all,
And lets say it had 102 entries, then you would have looped 1-101, leaving 102 out since you started at 0.
Related
I have this code block
<?php
$myArray = array('a', 'b', 'c');
foreach ($myArray as $k => $v) {
echo $v;
for ($i = 1; $i < 5; $i++) {
if ($i == $k) {
break;
}
echo $i; //a1234bc1
}
}
?>
and I have no problem with it until I get to the value after c. Shouldn't be 1234 instead of 1 ? am I missing something?
Because,
In the first iteration in foreach value of $k is 0 and there is no 0 in for loop, it covers all and print all 1 to 4, so output is a1234
In the second iteration in foreach value of $k is 1 and for loop start from 1,so in if condition it is in first iteration, so loop stop in first iteration of for loop and print only b , so output is a1234b
similarly in third iteration in foreach value of $k is 2 and for loop start from 1,so in if condition it is in second iteration, so loop stop in second iteration of for loop after print c1 , so output is a1234bc1
I think now its clear to you.
You foreach ($myArray as $k => $v) loop is executed 3 times as $myArray has 3 Elements.
First run
$k = 0 which is the index of the first element, $v = "a"
echo $v; // Outputs a
Output of your loop
for ($i = 1; $i < 5; $i++) { ... }
Outputs all numbers from 1 to 5 and stops once the exact value of $k is met. $k is 0 so the condition (break) never gets triggered. Hence all numbers from 1 to 5 are echoed.
Output so far:
a1234
Second run
$k = 1 which is the index of the second element, $v = "b"
for ($i = 1; $i < 5; $i++) { ... }
Output of your loop
for ($i = 1; $i < 5; $i++)
Outputs all numbers from 1 to 5 and stops once the exact value of $k is met. As $k is 1 the break gets executed on first run of llop, hence no output.
Output so far:
a1234b
Third run
$k = 2 which is the index of the third element, $v = "c"
echo $v; // Outputs c
Output of your loop
for ($i = 1; $i < 5; $i++) { ... }
Outputs all numbers from 1 to 5 and stops once the exact value of $k is met. As $k euqals 2 this time the loop gets executed once outputting 1. On second run the break executes and terminates oputput
Final output:
a1234bc1
1st Iteration:
1st loop
$k = 0; $v = a;
2nd loop
$i doesn't equal $k;
Output: a1234
2nd Iteration:
1st loop
$k = 1; $v = b;
2nd loop
$i equals $k(i.e 1);
Output: a1234b
3nd Iteration:
1st loop
$k = 2; $v = c;
2nd loop
$i equals $k(i.e 2);
Output: a1234bc1
Try this
$myArray = array('a', 'b', 'c');
foreach ($myArray as $k => $v) {
echo $v;
for ($i = 1; $i < 5; $i++) {
echo $i; //a1234b1234c1234
}
}
Remove if condition .
Well I'm stuck with this one.
I have a foreach loop nested in another foreach loop. Now on certain conditions I need to run the outer loop once again with the same key.
While there is this function prev($array), which would set the iterator to the previous position, this does not seem to work and the php docs says
As foreach relies on the >internal array pointer, changing it within the loop may lead to unexpected behavior.
The array I am working on is an associative array, so obviously I cannot easily switch to integer indexed iterations.
$arrLocalCopy = $this->arrPrintOut;
$groupCounter = 0;
foreach($this->arrPrintOut as $kOne => $rowA){
//first and last row contain titles and totals, so we skip them
if($groupCounter < 1 || $groupCounter == sizeof($this->arrPrintOut)-1 ){ $groupCounter++; continue; }
$rowCounter = 0;
foreach($arrLocalCopy as $k => $rowB){
//skip rows that are "before" the outer loops row, as we want to compare only rows below the row we compare to.
if ($rowCounter <= $groupCounter || $rowCounter == sizeof($arrLocalCopy)-1 ) { $rowCounter++; continue; }
//If those values are the same, then values belong to the same group and must be summed together.
if($rowA['t']==$rowB['t'] && $rowA['y']==$rowB['y'] && $rowA['g']==$rowB['g'] && $rowA['q']==$rowB['q'])
{
//if values are the same, then data belongs to one group, lets group them together.
$this->arrPrintOut[$kOne]['s'] += $rowB['s'];
$this->arrPrintOut[$kOne]['b'] += $rowB['b'];
$this->arrPrintOut[$kOne]['v'] += $rowB['v'];
$this->arrPrintOut[$kOne]['r'] += $rowB['r'];
$this->arrPrintOut[$kOne]['k'] += $rowB['k'];
$this->arrPrintOut[$kOne]['n'] += $rowB['n'];
$this->arrPrintOut[$kOne]['m'] += $rowB['m'];
$this->arrPrintOut[$kOne]['l'] += $rowB['l'];
unset($this->arrPrintOut[$k]); //row has been grouped to the current row, so we remove it from the array and from the copy.
unset($arrLocalCopy[$k]);
prev($this->arrPrintOut); //we need to run the outer loop with the same key again, as probably there is another row which could be grouped together with this row.
$groupCounter--;
}
$rowCounter++;
}
$groupCounter++;
}
Here is a code sample.
$rollback is a variable to check if we prev() already
$max is the number of iterations. If you prev() you have to increment it.
<?php
$array = array(1 => "a", 6 => "b", 19 => "c");
$rollback=0;
$max = sizeof($array);
for ($i=0; $i<$max; $i++) {
$key = key($array);
$value = $array[$key];
print "$key => $value\n";
next($array);
if ($value == "b" && $rollback == 0) {
prev($array);
$rollback = 1;
$max++;
}
}
I have code that will make an array or arrays of UNKNOWN length because it depends on how many new people have been added to the mysql DB. (this is where I'm getting confused)
The array has $x items, each item is an array of first name, last name, and e-mail address.
I want the loop to run till the array is ended.
$x = 0;
while($array[$x]['per_LastName'] != 'NULL') {
$batch[] = array('EMAIL'=>$array[$x]['per_Email'], 'FNAME'=>$array[$x]['per_FirstName'], 'LNAME'=>$array[$x]['per_LastName']);
$x = $x+1;
}
apparently I'm looping infinity because it uses all the memory.
Use a foreach loop which will loop through all elements of the array.
foreach($array as $key => $value) {
$batch[] = array('EMAIL'=>$value['per_Email'], 'FNAME'=>$value['per_FirstName'], 'LNAME'=>$value['per_LastName']);
}
Instead you should use a for loop
for($x = 0; $x<count($array); $x++){
$batch[] = array('EMAIL'=>$array[$x]['per_Email'], 'FNAME'=>$array[$x]['per_FirstName'], 'LNAME'=>$array[$x]['per_LastName']);
}
why not use foreach and avoid counters and unnecessary checks?
foreach($array as $eachArray)
{
$batch[] = array('EMAIL'=>$eachArray['per_Email'], 'FNAME'=>$eachArray['per_FirstName'], 'LNAME'=>$eachArray['per_LastName']);
}
How can I step forward 5 steps when using foreach to output an arrays value? So In this the put will be 1, 5
$array = ("1","2","3","4","5","6","7","8","9");
foreach ($array as &$value) {
echo $value; //Where do I tell it to move 5 paces forward?
echo "<br/ >";
}
If a foreach loop cannot be used, I'm willing to use something else. I don't think "while" or "for" can be used here?
$array = array("1","2","3","4","5","6","7","8","9");
for($i=0; $i<count($array); $i+=5) {
echo $array[$i];
echo "<br/ >";
}
I would use a while loop. Just set an index outside of the loop, and add 5 to it on each iteration of the loop. When the index is larger than the length of the list, terminate the loop.
A more compact way to express these instructions is a for loop:
for ($i=0; $i<count($array); $i = $i+5)
If it is not numerically indexed
$count = -1;
foreach ($array as &$value) {
$count++;
if ($count%4 != 0) continue;
echo "$value".PHP_EOL;
}
Having 3 multidimensional arrays, to whom I do a foreach how can I limit the multidimensional response inside foreach from X items to lets say 20.
Code:
$i = 0;
foreach ($value->channel->item as $item)
{
$data['data'][$keySection]['item1'][$i]['url'] = $item->url;
$data['data'][$keySection]['item1'][$i]['title'] = $item->title;
$data['data'][$keySection]['item1'][$i]['img'] = $item->thumb;
$i++;
}
where $value is contained within
foreach ($homeData as $keySection => $valueSection)
{
foreach($valueSection as $key => $value)
{
switch ($key)
{
I've tried aplying some fors both within foreach ($value->channel->item as $item) as outside but I just can't get it to work properly, I get either doubled results or not working at all.
How can I make this work??
Edit:
$i has nothing to do with it... I need to limit $value->channel->item where item contains X results
Edit2:
$i is for $homeData where $homeData contains three values and each and one of those will later contain 3 different values of $value->channel->item so if item contains 20 results, will be 3x20 = 60 and $i is ment to separate each 20 results...
Edit3:
ok, now I get it... sorry for the misunderstanding
After you start the foreach, add:
if($i > 19) {
break;
}
This checks if $i is greater than 19 (which means 20 iterations) and then breaks this foreach loop. More information about break, here.
You can do it like :
$i = 0;
foreach ($value->channel->item as $item)
{
if($i > 19) {
break;
}
$data['data'][$keySection]['item1'][$i]['url'] = $item->url;
$data['data'][$keySection]['item1'][$i]['title'] = $item->title;
$data['data'][$keySection]['item1'][$i]['img'] = $item->thumb;
$i++;
}
This will give you 20 items.
Hope this is what you want :)