PHP ForEach - how to jump to another index - php

I have a php foreach loop and would like to make a condition if true to jump to the index +2.
I know about continue that will go to the next, but my goal is to go to the actual_index + 2.
This is because I have a switch case and I need to do something inside.
I know also that this is possible with the for loop by setting manually the $i, but for the foreach loop, is it possible ?

You cannot do that with foreach(). Use for() instead to control the index yourself

I think you can best use the for loop, this gives you a little bit more control over the loop.
$array = [];
for($i = 0; $i < 100; $i++) {
if ($array[$i]) $i+=2;
}

Why not change your array to a stack? Looping it with a while clause and whenever you wish to skip 1, 2 or many more just pop or shift off from the array ( pop/shift based on the direction of your initial loop ofcourse ).

Related

How to break foreach loop from a XDebug session?

I have a foreach loop and that is doing some time consuming stuff:
$someHugeArray = [...]; // having beyond 300 to 1000 items
foreach ($someHugeArray as $item) {
$this->applyTimeConsumingMagic($item);
}
When debugging this I try to avoid iterating all of them items, so I am often writing escape code along the lines of:
foreach ($someHugeArray as $i => $item) {
$this->applyTimeConsumingMagic($item);
if ($i > 10) { break; } // #fixme: should not go live
}
And as the comment indicates, something like this did once go live making me feel like an amateur.
Is there some way to break the foreach loop from an XDebug session without writing var_dumpy code? As an IDE I use PhpStorm.
I did not find a way to break a foreach loop on the fly, yet the best next thing one can do is to decrease the array size on the fly.
Set a breakpoint after you set up your array, at best before the loop starts. (It does work inside the loop as well, yet could have weird behavior)
Select Evaluate expression phpstorm's debug window or use shortcut, default should be Alt + Shift + 8
run $someHugeArray = array_slice($someHugeArray, $offset = 0, $length = 10);
Besides array_slice one could also use array_filter if one wants to filter by more specific conditions using a closure.
Now you have a small array, enjoy fast execution time without having to worry to clean up after your debug session.
This will break the loop on the 10th run through - but obviously can be set to say 2 or 3 etc:
$myArray = $this->getHugeDataArray();
$i = 0; //here we set i to 0 so we can count to 10
foreach ($myArray as $key => $value)
{
$i++;
if ($i == 9) {break;}
//rest of actual code
}

in_array not working as intended

I am trying to prevent duplicates from occuring in a final array. I am trying to check for duplicates in a list of $media_candidate objects and compile them:
$iterator = 0;
// ensure items in final array are unique
while ((count($final_array) < $numResults) && ($iterator < count($media_data))) {
$media_candidate = $media_data[$iterator++];
if(!in_array($media_candidate['id'], $final_array)){
$final_array[] = $media_candidate;
}
}
As you can see in a print out of $final_array the last three elements are appearing 3 times with id, 343050519221992426_18478933. Any ideas as to what's going on?
First of all: You do not truncate the final array, so that all doublettes will end up at the end.
Second: You are reinventing the wheel: Read up on array_unique()
Edit
Third: After your edit, there is an even easier way:
$final_array=array();
foreach($media_data as $m) $final_array[$m['id']]=$m;
//You might want the next line or not
$final_array=array_values($final_array);
In essence you outsource the uniqueness to the hash keys of the array.
Try with:
if(!in_array($media_candidate['id'], $final_array)){
$final_array[] = $media_candidate['id'];
}
With $final_array[] you add new element at the end of the array.
You are checking $media_candidate['id'] but inserting $media_candidate in $final_array
Try array_unique function like this
$final_array = array_unique($media_candidate);

Change the auto increment amout in a foreach loop

Is there a way to make a foreach loop increment by more than one? I am loading a jquery script before each item in a foreach loop and I want the delay to increase by 300 for each item, so that each item animates separately as opposed to at the same time.
So is there another method other than $i++? Like $i++ + 300? Or I am reaching a little too far on this one?
Thanks everyone for responding so quickly. The $i+=300 was exactly what I was looking for. I used this variable to increase the delay time on each of the scripts so it is executed one at a time on each item in the loop. Here is a link to what I used it for. Thanks again!
http://cloudninelabs.com/c9v10/portfolio/
Basically you need to look after the counter yourself.
For example:
$i = 0;
foreach( $somelist as $index => $content ) {
// Do something with $content using $i
$i += 300;
}
Are you looking for something like this:
foreach (array(1, 2, 3, 4) as &$value) {
$value = $value + 300;
}
Your question is kinda unclear to me, but it seems like you can simply use i*300 as your animation interval (e.g. foreach ($foo as $i => $bar) { /*simply use $i*300 as your interval here*/ })
However, just FIY, n a regular for loop you can use $i+=300 (e.g. for ($i=0; $i<10000; $i+=300). It doesn't make much sense to do anything like that in an foreach loop. Instead, keep a separate variable to keep track of that and increase that be 300 every time ($i=0; foreach ($foo as $bar) { ... $i+=300 }).

How can I find out how many times a foreach construct loops in PHP, without using a "counter" variable?

If I have a foreach construct, like this one:
foreach ($items as $item) {
echo $item . "<br />";
}
I know I can keep track of how many times the construct loops by using a counter variable, like this:
$counter = 0;
$foreach ($items as $item) {
echo $item.' is item #'.$counter. "<br />";
$counter++;
}
But is it possible to do the above without using a "counter" variable?
That is, is it possible to know the iteration count within the foreach loop, without needing a "counter" variable?
Note: I'm totally okay with using counters in my loops, but I'm just curious to see if there is a provision for this built directly into PHP... It's like the awesome foreach construct that simplified certain operations which are clunkier when doing the same thing using a for construct.
No it's not possible unless your $items is an array having contiguous indexes (keys) starting with the 0 key.
If it have contiguous indexes do:
foreach ($items as $k => $v)
{
echo $k, ' = ', $v, '<br />', PHP_EOL;
}
But as others have stated, there is nothing wrong using a counter variable.
There's no easier way - that's kinda what count variables are for.
I'm assuming that you want to know the current count during the loop. If you just need to know it after, use count($items) as others have suggested.
You could tell how many time it WILL loop or SHOULD have looped by doing a
$loops = count($items);
However that will only work if your code does not skip an iteration in any way.
foreach loops N times, where N is just the size of the array. So you can use count($items) to know it.
EDIT
Of course, as noticed by Bulk, your loop should not break (or maybe continue, but I would count a continue as a loop, though shorter...)

How do I reindex an array after using unset()?

I'm having a little trouble with losing my array order after using unset(). This is the code I am using.
$id = $_GET['id'];
for ($i = 0; $i < count($my_array); $i++) {
if ($my_array[$i] == $id) {
unset($my_array[$i]);
}
}
Assume that $my_array has 4 items and $my_array[1] is equal to $id. After I unset that, I loop on $my_array and I get an Undefined Offset: 1 error. With print_r($my_array), I get $my_array[0], $my_array[2], and $my_array[3].
I understand perfectly why that's happening. Is there a way to re-index the array so that item 2 'drops' to item 1, and and the rest of the items respectively to the end of the array?
Something like reindex($my_array) would be sweet. I know I could run another for loop with a new array and transfer them manually, but a one step solution would be awesome. I just couldn't find anything anywhere.
Call array_values to reindex the array.
I just discovered you can also do a
array_splice($ar, 0, 0);
That does the re-indexing inplace, so you don't end up with a copy of the original array.

Categories