PHP Adding new key to the array used in foreach - php

How can I add to the array that I'm using foreach on?
for instance:
$t =array('item');
$c = 1;
foreach ($t as $item) {
echo '--> '.$item.$c;
if ($c < 10) {
array_push($t,'anotheritem');
}
}
this seems to produce only one value ('item1'). It seems that $t is only being evaluated once (at first time of foreach use) but not after it enters the loop.

foreach() will handle the array you pass into it as a static structure, it can't be dynamic as far as the number of iterations go. You can change the values by passing the value of the iteration by reference (&$value) but you can't add new ones in the same control structure.
for()
for() will let you add new ones, the limit you pass will be evaluated each time, so count($your_array) can be dynamic. Example:
$original = array('one', 'two', 'three');
for($i = 0; $i < count($original); $i++) {
echo $original[$i] . PHP_EOL;
if($i === 2)
$original[] = 'four (another one)';
};
Output:
one
two
three
four (another one)
while()
You can also define your own custom while() loop structure using a while(true){ do } methodology.
Disclaimer: Make sure if you're doing this that you define an upper limit on where your logic should stop. You're essentially taking over the responsibility of making sure that the loop stops somewhere here instead of giving PHP a limit like foreach() does (size of array) or for() where you pass a limit.
$original = array('one', 'two', 'three');
// Define some parameters for this example
$finished = false;
$i = 0;
$start = 1;
$limit = 5;
while(!$finished) {
if(isset($original[$i])) {
// Custom scenario where you'll add new values
if($i > $start && $i <= $start + $limit) {
// ($i-1) is purely for demonstration
$original[] = 'New value' . ($i-1);
}
// Regular loop behavior... output and increment
echo $original[$i++] . PHP_EOL;
} else {
// Stop the loop!
$finished = true;
}
}
See the differences here.

Thanks Scowler for the solution. It was posted in the comments and although he replied with an answer, it wasn't as simple as his first commented suggestion.
$t =array('item');
$c = 1;
for ($x=0; $x<count($t); $x++) {
$item = $t[$x];
echo '--> '.$item.$c;
if ($c < 10) {
array_push($t,'anotheritem');
}
$c++;
}
Works Great! count($t) is re-evaluated each time it goes through the loop.

Related

how do I make an array position equal a variable

what I want to do is run this for loop and within there is a foreach searching the positions. what I want to do is once there it returns false I want it to break and save the position of $i in a variable. I'm using simple_html_dom.php but I don't think that matters since this is more of a basic programming problem.
for($i = $0; $i < $20; $i++){
foreach($html->find('div[class=cate_link]',$i) as $a){
if (strpos($a->plaintext,'+info') == false){
break;
}
}
//this is not valid, but essentialy this is what I want to do.
$stop = $i;
}
To break multiple levels in a loop you simply specify the levels, eg, break 2 - see the manual on break - http://www.php.net/manual/en/control-structures.break.php.
As such your code might work as
for($i = $0; $i < $20; $i++){
foreach($html->find('div[class=cate_link]',$i) as $a){
if (strpos($a->plaintext,'+info') == false){
$stop = $i; // Set variable
break 2; // break both loops
// or alternatively force the outer loop condition to expire
//$i = 21; // Force the outer loop to exit
//break;
}
}
}
I have expanded to question to set $i = 21 to break the outer loop with a single break.
Untested code but syntax checked...
<?php
// Untested code...
// Assume that you WILL break out of the loops...
$currentForIdx = -1; // so we can test that 'for' loop actually ran
$quitLoops = false;
for($i = 0; $i < $20 && !quitLoops; $i++) {
$currentForIdx = $i; // in case we break out of the loops
foreach($html->find('div[class=cate_link]',$i) as $a){
if (strpos($a->plaintext,'+info') == false) {
$quitLoops = true;
break;
}
}
}
// test $quitLoops and $currentForIdx to work out what happened...
?>
I havent tested this, but I would try something like this:
for($i = $0; $i < $20; $i++){
$stop = false;
foreach($html->find('div[class=cate_link]',$i) as $a){
if (strpos($a->plaintext,'+info') == false){
$stop = $i;
}
}
if ($stop !== false) {break;}
}

PHP Return Loop Result

I am new to the world of coding as well as PHP and am wondering how I can use return when looping. For example I would like to return/display 1-10 however not use echo.
$start = 1;
$end = 11;
for($start; $start < $end; $start=$start+1) {
echo $start; //how can I use return?
}
Well, return will exit the function, so if you put return in a loop, the loop will only do one iteration (until the return statement).
You can collect all the values in an array and return the array:
function myFunction() {
$start = 1;
$end = 11;
$values = array();
for($start; $start < $end; $start=$start+1) {
$values[] = $start;
}
return $values;
}
That said, a function generating consecutive numbers already exists: range().
return is for sending the results of a function call back to the function or script that called it. It's the opposite of passing parameters to a function.
What you're doing is looping over a variable in the same scope, so return is not needed. Printing is done via echo or print. However, you may choose to build a value in that loop and print that once the loop is completed.
Additionally, if you're in a loop and you want to stop that loop immediately, use break; and if you want to skip the iteration you're on and go to the next one, use continue.
Here's some additional reading.
More clarification on continue. Say, for whatever reason, we don't want to do anything when $i is 6:
$start = 1;
$end = 11;
for ($i = $start; $i < $end; $i++)
// changed this to iterate over $i for readability/clarity
{
if ($start == 6)
{
// essentially, continue just skips this iteration of
// the loop, goes back to the top, iterates $i based on
// that third parameter in the for() declaration, and
// continues on.
continue;
}
echo $start; //how can I use return?
}
// output: 1234578910
just use
function foobar()
{
$output = '';
for ( $i = 1 ; $i <= 10 ; $i++ )
{
$output .= $i;
}
return $output
}
echo foobar();
You can achieve it by defining a variable you want to return inside and outside the loop with .=.
Here is a working example:
function my_function() {
// I am the variable to be return-ed
$k = "My World<br/>";
for ($z=1; $z<=3; $z++) {
$v = 'Here'.$z;
// I am the same variable but I am going inside the loop
$k .= $v . "<br/>";
}
//I am not always important to be here!
$k .= "Is Awesome";
// This is the show time..
return $k;
}
my_function();
Output:
My World
Here1
Here2
Here3
Is Awesome
Return will end the function that you are currently in. The scenario you have given us is not a good scenario to use the return function.
The example below will do the same as your code, but uses a function as well as your for loop. Hope this answeres your question.
$start = 11;
$end = 20;
for($start; $start <= $end; $start++){
echo calculateValue($start);
}
function calculateValue($value){
return $value - 10;
}
function loop_kec($ar_kec) {
$total_data = count($ar_kec) - 1;
//$return_kec = array();
for ($e = 0; $e < $total_data; $e++) {
$return_kec .= 'kecamatan = ' . "'$ar_kec[$e]'" . ' or ';
}
$return_kec .= 'kecamatan = ' . "'$ar_kec[$total_data]'";
return $return_kec;
}

PHP: What's the difference between static variable inside a for loop and a non-static variable outside the for loop?

For example, what's the difference between
$foobar = 0
for ($i=0; $i<20; $i++) {
//do something using $foobar
$foobar++;
}
and
for ($i=0; $i<20; $i++) {
static $foobar = 0
//do something using $foobar
$foobar++;
}
???
Both of the above examples have different results than from the following:
for ($i=0; $i<20; $i++) {
$foobar = 0
//do something using $foobar
$foobar++;
}
All three variations have a different outcome. I understand that in the first of the three examples the value of the $foobar variable gets larger and larger and that in the third example the value of the $foobar variable gets reset during each loop. I'm not sure what's going on with the example using the static $foobar variable. It would seem that the first two examples should behave the same in the portion of the for loop where $foobar is used, but that is not the case for me.
For reference, here's my actual code (the algorithm is not complete yet). I've marked the for() loop that has me thinking about this topic:
function combine($charArr, $k) {
$currentsize = sizeof($charArr);
static $combs = array();
static $originalsize = "unset";
if ($originalsize === "unset") $originalsize = $currentsize;
static $firstcall = true;
if ($originalsize >= $k) {
$comb = '';
if ($firstcall === true) {
for ($i = $originalsize-$k; $i < $originalsize; $i++) {
$comb .= $charArr[$i];
}
$combs[] = $comb;
$firstcall = false;
}
if ($currentsize > $k) {
$comb = ''; //reset
for ($i=0; $i<$k; $i++) {
$comb .= $charArr[$i];
}
$combs[] = $comb;
//########### THE FOR LOOP IN QUESTION ###########
for ($i = $k-1; $i >= 0; $i--) {
static $range_adj = 0;
for ( $j = $i+1; $j < $currentsize-$range_adj; $j++ ) {
if ( !($i == 0 and $j == $currentsize-$range_adj-1) ) {
$comb = substr_replace($comb, $charArr[$j], $i, 1);
$combs[] = $comb;
}
}
$range_adj++;
}
if ($currentsize-1 > $k) {
array_splice($charArr, 0, 1);
combine($charArr, $k);
}
}
$output = array_values( $combs );
unset($combs);
return $output;
}
else {
return false;
}
}
If I remove the $range_adj variable from for loop and place it right before the said for loop as a none-static variable, then the result of my function is not the same. Here's what the modified for loop would look like:
$range_adj = 0;
for ($i = $k-1; $i >= 0; $i--) {
for ( $j = $i+1; $j < $currentsize-$range_adj; $j++ ) {
if ( !($i == 0 and $j == $currentsize-$range_adj-1) ) {
$comb = substr_replace($comb, $charArr[$j], $i, 1);
$combs[] = $comb;
}
}
$range_adj++;
}
The fact that I get two different outcomes leads me to believe that something is different with each method, because if the two methods produced identical results, then the outcome of my function would be the same in both scenarios, which is not the case when I test these scenarios. Why am I getting two results? Test my function out with both methods of the for loop implemented and you will also get varying results.
For your convenience, here's the original method:
for ($i = $k-1; $i >= 0; $i--) {
static $range_adj = 0;
for ( $j = $i+1; $j < $currentsize-$range_adj; $j++ ) {
if ( !($i == 0 and $j == $currentsize-$range_adj-1) ) {
$comb = substr_replace($comb, $charArr[$j], $i, 1);
$combs[] = $comb;
}
}
$range_adj++;
}
???
It seems to me that the results should be exactly the same, but they are not. If you run my function, you will notice that you get a different result with each method of the for loop.
The first and second loops appear to do the same thing. This is because, as with any other statically-initialized variable, static means you only initialize it once. It retains its value as you try to access it again. You'll find that the static $foobar will still exist outside the scope of the loop wherever you declare/initialize it; this is due to the nature of PHP and has nothing to do with the static variable.
The difference is made clear only when you attempt to access $foobar before the loop: it won't be declared yet in the second snippet because you only create it within the loop, so you may get an undefined-variable notice.
static $foobar = 0;
initializing once, other execute of static $foobar = 0 not do anything with $foobar variable
Above two prog have same output, but your last prog have variable which is reset during each loop.
when you use "Static" key word for any variable initialization then It retains untill you not destroy it.. or not destroy your program session.
You can use static in this fashion to prevent a variable from being reinitialized inside a loop.
in the first iteration if the static variable is not initialize then it would create it and keep it within the outer context, on every other iteration PHP Would just skip it as its already been initialized.
Both results prevail the same: http://codepad.org/evilks4R
The reason why it differs in your function is that your function is recursive which means the function combine calls combine from within itself, when taking out the static keyword on the second call of combine, the variable is being reinitialized thus making the results differ.
using the static keyword allows you to pass the arguments to the second call with there values that was produced in the third value.
here's an example of passing static members to the latter passes of a function call: http://codepad.org/gChjx7Om
if you had done:
$foo_bar = 0;
for(.....)
this would be within a function so that $foo_bar would get reset to 0 every time the function was called, therefore overwriting the last calls calculations.
if you moved the $foo_bar outside the function, and then where needed in the function you added:
global $foo_bar
you would have the same results.
http://www.cprogramming.com/tutorial/statickeyword.html

Pull elements from next foreach item in PHP?

I'm doing a PHP 'traffic light' style warning system for my website, that basically says' if there is X percentage change between the current array entry and the next one, throw an error'.
So, I'm looping through my array elements in a foreach loop, however need to be able to do something like this: (note: this is just a basic example, but should be enough to get the idea)
foreach($array as $a)
{
$thisValue = $a['value'];
$nextValue = next($a['value']);
$percentageDiff = ($nextValue-$thisValue)/$thisValue;
}
I've put next() tags to get the next value but understand this only works for arrays. IS there something else I can use to get the next foreach item?
Thanks for your time!
do it the other way, and store the previous entry and compare those.
$prev = null;
foreach ($item as $i){
if ($prev !== null){
diff($prev, $i);
}
$prev = $i
}
Simple answer: don't use a foreach loop. Use a simple for loop instead:
for ($i = 0; $i < count($array); $i++) {
if (isset($array[$i + 1])) {
$thisValue = $array[$i]['value'];
$nextValue = $array[$i + 1]['value'];
$percentageDiff = ($nextValue-$thisValue)/$thisValue;
}
}
You should be able to use:
foreach($array as $a)
{
$array_copy = $array;
$thisValue = $a['value'];
$nextValue = next($array_copy);
$nextValue = $nextValue['value'];
$percentageDiff = ($nextValue-$thisValue)/$thisValue;
}
This copies the array and then moves the pointer along by 1.
The easiest solution IMO is to change your mindset. Instead of inspecting the current and the next record, inspect the previous and the current record. Remembering the previous one is easier than getting the next one.
If you don't want that, you can also ditch the foreach and iterate C-style using for and a counter variable - one cavet though: PHP's sparse arrays can bite you, so you best call array_values() on the inspected array before iterating.
If you want to work with foreach, you could compare the current value with the previous value instead of with the next value:
$previous = null;
foreach ($array as $a) {
if (!is_null($previous)) {
$thisValue = $previous['value'];
$nextValue = $a['value'];
$percentageDiff = ($nextValue-$thisValue)/$thisValue;
}
$previous = $a;
}
With this you just shift the whole iteration by one item.
Why not just use a normal for loop rather than the foreach iterator?
<?php
$testArray = array(10,20,30,40,50,60,70,80,90,100);
$elementCount = count($testArray);
for($loop=0; $loop<$elementCount; $loop++) {
$thisValue = $testArray[$loop];
// Check if there *is* a next element.
$nextValue = $loop + 1 < $elementCount ? $testArray[$loop + 1] : null;
// Calculate the percentage difference if we have a next value.
if($nextValue) $percentageDiff = ($nextValue-$thisValue)/$thisValue;
}
?>
'It is usually easier to use the previous value than the next:
$lastValue = NULL;
foreach ($array as $a) {
if ($lastValue === NULL) {
$lastValue = $a['value'];
continue;
}
$percentageDiff = ($a['value'] - $lastValue) / $lastValue;
$lastValue = $a['value'];
}
for($i=0;$i<count($array);$i++) {
$thisValue = $array[$i];
$nextValue = $array[i+1]; // will not be set if $i==count($array)-1
$percentageDiff = ($nextValue-$thisValue)/$thisValue;
}
There are indeed array iterator functions which support what you need, and also simply looping thorugh an array with next() / prev() etc works fine but the solution above is more elegant
It doesn't work with foreach because foreach creates a copy of references and doesn't set the array pointers in the array itself.
Here is a sample which can be used for associative arrays using array iterator functions:
$arrayobject = new ArrayObject($array);
$iterator = $arrayobject->getIterator();
for($i=0;$i<count($array);$i++) {
$iterator->seek($i);
$thisValue = $iterator->current();
$iterator->seek($i+1);
$nextValue = $iterator->current();
$percentageDiff = ($nextValue-$thisValue)/$thisValue;
}

PHP Foreach loop take an additional step forward from within the loop

Basically I have a foreach loop in PHP and I want to:
foreach( $x as $y => $z )
// Do some stuff
// Get the next values of y,z in the loop
// Do some more stuff
It's not practical to do in a foreach.
For non-associative arrays, use for:
for ($x = 0; $x < count($y); $x++)
{
echo $y[$x]; // The current element
if (array_key_exists($x+1, $y))
echo $y[$x+1]; // The next element
if (array_key_exists($x+2, $y))
echo $y[$x+2]; // The element after next
}
For associative arrays, it's a bit more tricky. This should work:
$keys = array_keys($y); // Get all the keys of $y as an array
for ($x = 0; $x < count($keys); $x++)
{
echo $y[$keys[$x]]; // The current element
if (array_key_exists($x+1, $keys))
echo $y[$keys[$x+1]]; // The next element
if (array_key_exists($x+2, $keys))
echo $y[$keys[$x+2]]; // The element after next
}
When accessing one of the next elements, make sure though that they exist!
use the continue keyword to skip the rest of this loop and jump back to the start.
Not sure if you simply want to do just "some stuff" with the first element, only "some more stuff" with the last element, and both "some stuff" and "some more stuff" with every other element. Or if you want to do "some stuff" with the first, third, fifth elements, and "some more stuff" with the second, fouth, sixth elements, etc.
$i = 0;
foreach( $x as $y => $z )
if (($i % 2) == 0) {
// Do some stuff
} else {
// Do some more stuff
}
$i++;
}
Ok, following up on my comment on Pekka's solution, here is one that takes into account the fact that the array might be associative. It's not pretty, but it works. Suggestions on how to improve this are welcomed!
<?php
$y = array(
'1'=>'Hello ',
'3'=>'World ',
'5'=>'Break? ',
'9'=>'Yup. '
);
$keys = array_keys($y);
$count = count($y);
for ($i = 0; $i < $count; $i++) {
// Current element
$index = $keys[$i];
echo "Current: ".$y[$index]; // The current element
if (array_key_exists($i+1, $keys)) {
$index2 = $keys[$i+1];
echo "Next: ".$y[$index2]; // The next element
}
if (array_key_exists($i+2, $keys)) {
$index3 = $keys[$i+2];
echo "Nextnext: ".$y[$index3]; // The element after next
}
}
?>
try something like...
for ($i=0, $i<count($x); $i++)
{
// do stuff with $x[$i]
// do stuff with $x[$i+1], unless you're on the last element of the array
}
reset($arr);
while(list($firstindex,$firstvalue) = each($arr)){
list($secondindex,$secondvalue) = each($arr);
//do something with first & second.
}

Categories