forloop continue again after end of the iteration - php

I used function with same logic given below
Given below code is sample of same logic i used, i need to continue the for loop after end of the iteration, i assign 0 to the variable $j at end so forloop need to continue, why its closed the process.
for($i=$j;$i<7;$i++){
echo "<br/>".$i;
if($i == 6){$j=0;continue;}
}
Actual Output
1
2
3
4
5
6
Expected output
1
2
3
4
5
6
1
2
3
4
5
6
.....etc
My Original code sample is
foreach($Qry_Rst as $key=>$Rst_Val){
for($j=$ItrDt;$j<7;$j++){
$ItrDate = date('Y-m-d', mktime(0, 0, 0, $month, $day + $j, $year));
if($ItrDate == $Rst_Val['sloat_day']){
$TimeTableAry[$loop_itr] = $Rst_Val;
break
}
}
}

The doc says
The first expression (expr1) is evaluated (executed) once unconditionally at the beginning of the loop.
So instead of $j just use $i to reset the loop. As this (demo)
$j = 1;
$current = 0;
for ($i=$j; $i<4; $i++) {
printf("i: %d, j: %d\n", $i, $j);
if ($i==3 && $current < 5) {
$i = -1;
$j = mt_rand(0,3);
$current++;
continue;
}
}
shows, you actually need to reset $i = -1; so it will be 0 after $i++ will be evaluated.
But with this you'll have an if in every iteration of the loop although you only need it for one. Basically you don't need it for the iteration itself but only to start a next one, so there must be something else here.
function doFor($data, $callback) {
$dataLength = count($data);
for ($i=0; $i<$dataLength; $i++) {
call_user_func($callback, $data[$i]);
}
return $data;
}
Isolating the loop into its own function will allow for one line that will execute the wanted callback allowing your main code to be something like (demo)
$data = array(array("foo","bar"),array("hello"),array("world","!"));
function justDump($obj) {
var_dump($obj);
};
$i = 0;
do {
$data = doFor($data, 'justDump');
print "<br>";
$i++;
} while($i<5);

You can also try the way you originally wanted (only slightly edited):
//counter to avoid infinite loop
$counter = 0;
for($i=$i;$i<7;$i++){
echo "<br/>".$i;
if($i == 6){
$i=0;
$counter++;
continue;
}
if($counter == 5){break;}
}
1
2
3
4
5
6
1
2
3
...

Related

PHP stuck with the loop excercise

I am stuck with this php loop. Then n = 3, k = 5, s = 21.
Can anyone help me please ?
Rows 3. In the first row 5 chairs:
1 row: ⑁⑁⑁⑁⑁ (5 chairs)
2 row: ⑁⑁⑁⑁⑁⑁⑁ (7 chairs)
3 row: ⑁⑁⑁⑁⑁⑁⑁⑁⑁ (9 chairs)
Chairs in total: 21
<?php
for ($i=0; $i<=6; $i++) {
for ($j=0; $j<$i; $j++) {
if($i == 1) {
echo '';
}else{
echo '&#9281';
}
} echo ' ';
}
?>
If I understand correctly what you want,
$n is number of row you needed,
$k number of chair at row 1.
Each row chair is added by two.
<?php
$n = 3;
$k = 5;
for($i = 0; $i < $n; $i++) {
if($i >= 1) {
echo PHP_EOL;
}
echo str_repeat('-', $k + ($i * 2));
}
Example: When n = 3 and k = 8, it must be obtained that order s = 30 chairs.
Create a PHP solution that specifies the N-row queue in the variables, K-how many chairs should be in the first row.
For example: N = 3; K = 5;
After loading the page (after performing the program actions with the variables available) the following should be displayed:
Rows 3. First row 5 chairs:
Queue 1: ⑁⑁⑁⑁⑁ (5 chairs)
Queue 2: ⑁⑁⑁⑁⑁⑁⑁ (7 chairs)
Queue 3: ⑁⑁⑁⑁⑁⑁⑁⑁⑁ (9 chairs)
Total required chairs: 21
I think you want to use 'if' syntax. Is it right?
If it's not correct, You should describe your work more detail
<?php
// ...
for($i = 0; $i< sizeof($rows); $i++ ){
if ($i % 2 == 0) {
print "It's even";
}
}
// ... If a row is an Array, use this one.
for($i = 0; $i< sizeof($rows); $i++ ){
for($j = 0; $j< sizeof($rows[$i]); $j++ ){
if ($j % 2 == 0) {
print "It's even index of a row";
//do Something.
}
}
}
?>

Decoding function to better understand

I am revisiting PHP and want to relearn where i lack and i found one problem, i am unable to understand the following code, where as it should output 6 according to the quiz, i got it from but i broke it down to simple pieces and commented out to better understand, according to me the value of $sum should be 4, but what i am doing wrong, maybe my breakdown is wrong?
$numbers = array(1,2,3,4);
$total = count($numbers);
//$total = 4
$sum = 0;
$output = "";
$i = 0;
foreach($numbers as $number) {
$i = $i + 1;
//0+1 = 1
//0+2 = 2
//0+3 = 3
//0+4 = 4
if ($i < $total) {
$sum = $sum + $number;
//1st time loop = 0 < 4 false
//2nd time loop = 0 < 1 false
//3rd time loop = 0 < 2 false
//5th time loop = 0 < 3 false
//6th time loop = 4 = 4 true
//$sum + $number
//0 + 4
//4
}
}
echo $sum;
This is very basic question and might get down vote but it is also a strong backbone for people who want to become PHP developer.
You don't understand the last part in the loop. It actually goes like this now:
if($i < $total) {
$sum = $sum + $number;
//1st time loop: $sum is 0. $sum + 1 = 1. $sum is now 1.
//2nd time loop: $sum is 1. $sum + 2 = 3. $sum is now 3.
//3rd time loop: $sum is 3. $sum + 3 = 6. $sum is now 6.
//4th time loop: it doesn't get here. $i (4) < $total (4)
//This is false, so it doesn't execute this block.
}
echo $sum; // Output: 6
I altered your script a little so that it will print out what it's doing as it goes. I find it useful to do this kind of thing if I'm having a hard time thinking through a problem.
$numbers = array(1,2,3,4);
$total = count($numbers);
$sum = 0;
$i = 0;
$j = 0;
foreach($numbers as $number) {
$i = $i + 1;
echo "Iteration $j: \$i +1 is $i, \$sum is $sum, \$number is $number";
if ($i < $total) {
$sum = $sum + $number;
echo ", \$i is less than \$total ($total), so \$sum + \$number is: $sum";
} else {
echo ", \$i is not less than \$total ($total), so \$sum will not be increased.";
}
echo '<br>'; // or a new line if it's CLI
$j++;
}
echo $sum;
Lets Explain
Your initial value of $i is 0 but when you start looping you increment it by 1, so the start value of $i is 1.
When checking the condition you did't use equal sign to check for the last value whether you start value is 1. So its clear that your loop must be run for 1 less of total.
$i = 0;
foreach($numbers as $number) {
$i += 1;
if ($i < $total)
$sum += $number;
}
echo $sum;
Analysis
Step: 1 / 4
The value of $number is: 1 And The value of $i is: 1
Step: 2 / 4
The value of $number is: 2 And The value of $i is: 2
Step: 3 / 4
The value of $number is: 3 And The value of $i is: 3
When the loop again go for a check the value of $i increased by 1 and at 4. So trying to match the condition if ($i < $total), where the value of $i and $total is equal, so it will return false. So the loop only run for 3 time.
Result
6

Step inside foreach

How to do something every 5 (for example) cycles inside foreach?
I'm add $i++ How to check it by step?
Use modulo to determine offset.
$i = 0;
foreach ($array as $a) {
$i++;
if ($i % 5 == 0) {
// your code for every 5th item
}
// your inside loop code
}
Unless you're doing something separately in each iteration, don't.
Use a for loop and increment the counter by 5 each time:
$collectionLength = count($collection);
for($i = 0; $i < $collectionLength; i+=5)
{
// Do something
}
Otherwise, you can use the modulo operator to determine if you're on one of the fifth iterations:
if(($i + 1) % 5 == 0) // assuming i starts at 0
{
// Do something special this time
}
for($i = 0; $i < $items; $i++){
//for every 5th item, assuming i starts at 0 (skip)
if($i % 5 == 0 && $i != 0){
//execute your code
}
}

How do I distribute values of an array in three columns?

I need this output..
1 3 5
2 4 6
I want to use array function like array(1,2,3,4,5,6). If I edit this array like array(1,2,3), it means the output need to show like
1 2 3
The concept is maximum 3 column only. If we give array(1,2,3,4,5), it means the output should be
1 3 5
2 4
Suppose we will give array(1,2,3,4,5,6,7,8,9), then it means output is
1 4 7
2 5 8
3 6 9
that is, maximum 3 column only. Depends upon the the given input, the rows will be created with 3 columns.
Is this possible with PHP? I am doing small Research & Development in array functions. I think this is possible. Will you help me?
For more info:
* input: array(1,2,3,4,5,6,7,8,9,10,11,12,13,14)
* output:
1 6 11
2 7 12
3 8 13
4 9 14
5 10
You can do a loop that will automatically insert a new line on each three elements:
$values = array(1,1,1,1,1);
foreach($values as $i => $value) {
printf('%-4d', $value);
if($i % 3 === 2) echo "\n";
}
EDIT: Since you added more information, here's what you want:
$values = array(1,2,3,4,5);
for($line = 0; $line < 2; $line++) {
if($line !== 0) echo "\n";
for($i = $line; $i < count($values); $i+=2) {
printf('%-4d', $values[$i]);
}
}
And if you want to bundle all that in a function:
function print_values_table($array, $lines = 3, $format = "%-4d") {
$values = array_values($array);
$count = count($values);
for($line = 0; $line < $lines; $line++) {
if($line !== 0) echo "\n";
for($i = $line; $i < $count; $i += $lines) {
printf($format, $values[$i]);
}
}
}
EDIT 2: Here is a modified version which will limit the numbers of columns to 3.
function print_values_table($array, $maxCols = 3, $format = "%-4d") {
$values = array_values($array);
$count = count($values);
$lines = ceil($count / $maxCols);
for($line = 0; $line < $lines; $line++) {
if($line !== 0) echo "\n";
for($i = $line; $i < $count; $i += $lines) {
printf($format, $values[$i]);
}
}
}
So, the following:
$values = range(1,25);
print_array_table($values);
Will output this:
1 10 19
2 11 20
3 12 21
4 13 22
5 14 23
6 15 24
7 16 25
8 17
9 18
One solution is to cut the array into chunks, representing the columns, and then print the values in row order:
$cols = array_chunk($arr, ceil(count($arr)/3));
for ($i=0, $n=count($cols[0]); $i<$n; $i++) {
echo $cols[0][$i];
if (isset($cols[1][$i])) echo $cols[1][$i];
if (isset($cols[2][$i])) echo $cols[2][$i];
}
If you don’t want to split your array, you can also do it directly:
for ($c=0, $n=count($arr), $m=ceil($n/3); $c<$m; $c++) {
echo $arr[$c];
for ($r=$m; $r<$n; $r+=$m) {
echo $arr[$c+$r];
}
}
$a = array(1,2,3,4,5);
"{$a[0]} {$a[1]} {$a[2]}\n{$a[3]} {$a[4]}";
or
$a = array(1,2,3,4,5);
"{$a[0]} {$a[1]} {$a[2]}".PHP_EOL."{$a[3]} {$a[4]}";
or
$a = array(1,2,3,4,5);
$second_row_start = 3; // change to vary length of rows
foreach( $a as $index => $value) {
if($index == $second_row_start) echo PHP_EOL;
echo "$value ";
}
or, perhaps if you want a longer array split into columns of 3?
$a = array(1,2,3,4,5,6,7,8,9,10,11,12,13);
$row_length = 3; // change to vary length of rows
foreach( $a as $index => $value) {
if($index%$row_length == 0) echo PHP_EOL;
echo "$value ";
}
which gives
1 2 3
4 5 6
7 8 9
10 11 12
13
one solution is :
your array has N elements, and you want 3 columns, so you can get the value of each cell with $myarray[ column_index + (N/3) + line_index ] (with one or two loops for columns and lines, at least for lines)
I hope this will help you
Bye
Here's something I whipped up. I'm pretty sure this could be more easily accomplished if you were using HTML lists, I've assumed you can't use them.
$arr = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14, 15, 16);
$max = count($arr);
$cols = 3;
$block = ceil($max / $cols);
for ($i = 0; $i < $block ; $i++) {
echo $arr[$i] . ' ';
for ($j = 1; $j < $cols; $j++) {
$nexKey = $i + $block * $j;
if (!isset($arr[$nexKey])) break;
echo $arr[$nexKey] . ' ';
}
echo '<br>';
}
NOTE : You can easily refactor the code inside the loop that uses $nexkey variable by making it into a loop itself so that it works for any number of columns. I've hardcoded it.
Uses loops now.

PHP: Next Available Value in an Array, starting with a non-indexed value

I've been stumped on this PHP issue for about a day now. Basically, we have an array of hours formatted in 24-hour format, and an arbitrary value ($hour) (also a 24-hour). The problem is, we need to take $hour, and get the next available value in the array, starting with the value that immediately proceeds $hour.
The array might look something like:
$goodHours = array('8,9,10,11,12,19,20,21).
Then the hour value might be:
$hour = 14;
So, we need some way to know that 19 is the next best time. Additionally, we might also need to get the second, third, or fourth (etc) available value.
The issue seems to be that because 14 isn't a value in the array, there is not index to reference that would let us increment to the next value.
To make things simpler, I've taken $goodHours and repeated the values several times just so I don't have to deal with going back to the start (maybe not the best way to do it, but a quick fix).
I have a feeling this is something simple I'm missing, but I would be so appreciative if anyone could shed some light.
Erik
You could use a for loop to iterate over the array, until you find the first that is greater than the one you're searching :
$goodHours = array(8,9,10,11,12,19,20,21);
$hour = 14;
$length = count($goodHours);
for ($i = 0 ; $i < $length ; $i++) {
if ($goodHours[$i] >= $hour) {
echo "$i => {$goodHours[$i]}";
break;
}
}
Would give you :
5 => 19
And, to get the item you were searching for, and some after that one, you could use something like this :
$goodHours = array(8,9,10,11,12,19,20,21);
$hour = 14;
$numToFind = 2;
$firstIndex = -1;
$length = count($goodHours);
for ($i = 0 ; $i < $length ; $i++) {
if ($goodHours[$i] >= $hour) {
$firstIndex = $i;
break;
}
}
if ($firstIndex >= 0) {
$nbDisplayed = 0;
for ($i=$firstIndex ; $i<$length && $nbDisplayed<$numToFind ; $i++, $nbDisplayed++) {
echo "$i => {$goodHours[$i]}<br />";
}
}
Which would give you the following output :
5 => 19
6 => 20
Basically, here, the idea is to :
advance in the array, until you find the first item that is >= to what you are looking for
get out of that first loop, when found
If a matching item was found
loop over the array, until either its end,
or you've found as many items as you were looking for.
You can also use the SPL FilterIterator. Though it's not the fastest solution there is, it has the advantage that you can "prepare" the iterator somewhere/anywhere and then pass it to a function/method that doesn't have to know how the iterator works on the inside, i.e. you could pass a completely different iterator the next time.
class GreaterThanFilterIterator extends FilterIterator {
protected $threshold;
public function __construct($threshold, Iterator $it) {
$this->threshold = $threshold;
parent::__construct($it);
}
public function accept() {
return $this->threshold < parent::current();
}
}
function doSomething($it) {
// no knowledge of the FilterIterator here
foreach($it as $v) {
echo $v, "\n";
}
}
$goodHours = array(8,9,10,11,12,19,20,21);
$it = new GreaterThanFilterIterator(14, new ArrayIterator($goodHours));
doSomething($it);
prints
19
20
21
As $goodHours is already sorted, that's something easy:
$next = 0;
foreach($goodHours as $test)
if($test > $hour && $next = $test)
break;
After that four-liner (that can be written in a smaller number of lines naturally), $next is either 0 if $hour could not be matched in $goodHours or it contains the value that immediately proceeds $hour. That is what you asked for.
This only works when $goodHours is sorted, in case it's not, you can sort it by using the asort() function.
Try this function:
function nextValueGreaterThan($haystack, $needle, $n=1) {
sort($haystack);
foreach ($haystack as $val) {
if ($val >= $needle) {
$n--;
if ($n <= 0) {
return $val;
}
}
}
}
$goodHours = array(8,9,10,11,12,19,20,21);
echo nextValueGreaterThan($goodHours, 14); // 19
echo nextValueGreaterThan($goodHours, 14, 3); // 21
Here's an answer similar to the rest of these, including an optional "offset" parameter, that gets your n'th item past the de-facto first one.
class GoodHours {
private $hours = array(8,9,10,11,12,19,20,21);
public function getGoodHour($hour, $offset = 0) {
$length = count($this->hours);
for ($i = 0 ; $i < $length && $this->hours[$i] < $hour ; $i++)
; // do nothing
return $this->hours[($i + $offset) % $length];
}
}
// some test values
$good = new GoodHours();
$x = $good->getGoodHour(5); // 8
$x = $good->getGoodHour(5,1); // 9
$x = $good->getGoodHour(5,2); // 10
$x = $good->getGoodHour(10); // 10
$x = $good->getGoodHour(10,1); // 11
$x = $good->getGoodHour(10,2); // 12
$x = $good->getGoodHour(21); // 21
$x = $good->getGoodHour(21,1); // 8
$x = $good->getGoodHour(21,2); // 9
$x = $good->getGoodHour(21); // 8
$x = $good->getGoodHour(22,1); // 9
$x = $good->getGoodHour(22,2); // 10

Categories