How to Skip Elements in Foreach Loop

how to skip elements in foreach loop

Five solutions come to mind:

Double addressing via array_keys

The problem with for loops is that the keys may be strings or not continues numbers therefore you must use "double addressing" (or "table lookup", call it whatever you want) and access the array via an array of it's keys.

// Initialize 25 items
$array = range( 1, 25, 1);

// You need to get array keys because it may be associative array
// Or it it will contain keys 0,1,2,5,6...
// If you have indexes staring from zero and continuous (eg. from db->fetch_all)
// you can just omit this
$keys = array_keys($array);
for( $i = 21; $i < 25; $i++){
echo $array[ $keys[ $i]] . "\n";
// echo $array[$i] . "\n"; // with continuous numeric keys
}


Skipping records with foreach

I don't believe that this is a good way to do this (except the case that you have LARGE arrays and slicing it or generating array of keys would use large amount of memory, which 68 is definitively not), but maybe it'll work: :)

$i = 0;
foreach( $array as $key => $item){
if( $i++ < 21){
continue;
}
echo $item . "\n";
}


Using array slice to get sub part or array

Just get piece of array and use it in normal foreach loop.

$sub = array_slice( $array, 21, null, true);
foreach( $sub as $key => $item){
echo $item . "\n";
}


Using next()

If you could set up internal array pointer to 21 (let's say in previous foreach loop with break inside, $array[21] doesn't work, I've checked :P) you could do this (won't work if data in array === false):

while( ($row = next( $array)) !== false){
echo $row;
}

btw: I like hakre's answer most.



Using ArrayIterator

Probably studying documentation is the best comment for this one.

// Initialize array iterator
$obj = new ArrayIterator( $array);
$obj->seek(21); // Set to right position
while( $obj->valid()){ // Whether we do have valid offset right now
echo $obj->current() . "\n";
$obj->next(); // Switch to next object
}

Skip first iteration during forEach loop

you need to check index, and use return on that value, what you need. In your case you need to skip zero index (0), here is code

const cars = ['audi', 'bmw', 'maybach']

cars.forEach((car, index) => {
if (index === 0) return;
console.log(car)
});

this code will show 'bmw' and 'maybach'

PHP foreach loop skip first 3 items

For simplicity you could repeat the foreach statement but doing the opposite and continue on the first three items.

<?php foreach ($_productCollection as $_product): ?>
<?php
$count++; // Note that first iteration is $count = 1 not 0 here.
if($count <= 3) continue; // Skip the iteration unless 4th or above.
?>
<li class="category-row-list-item">
<a class="product-name" href="<?php echo $_product->getProductUrl() ?>">
<?php echo $this->htmlEscape($_product->getName()) ?>
</a>
</li>
<?php endforeach ?>

The keyword continue is used in loops to skip the current iteration without exiting the loop, in this case it makes PHP go directly back to the first line of the foreach-statement, thus increasing counter to 4 (since 4th, 5th and 6th is what we're after) before passing the if statement.

Commentary on the approach

I kept it coherent with your existing solution but a more clean way in this case would probably be to use the built in Collection Pagination.

If you use ->setPageSize(3) you can simply iterate the collection to get the first three products and then use ->setCurPage(2) to get the second page of three items.

I'm linking this blog post on the topic here just to give you an example of how it's used but since I don't know your comfort level in working with collections I retain my first answer based on your existing code.

How do I skip an iteration of a `foreach` loop?

You want:

foreach (int number in numbers) //   <--- go back to here --------+
{ // |
if (number < 0) // |
{ // |
continue; // Skip the remainder of this iteration. -----+
}

// do work
}

Here's more about the continue keyword.


Update: In response to Brian's follow-up question in the comments:

Could you further clarify what I would do if I had nested for loops, and wanted to skip the iteration of one of the extended ones?

for (int[] numbers in numberarrays) {
for (int number in numbers) { // What to do if I want to
// jump the (numbers/numberarrays)?
}
}

A continue always applies to the nearest enclosing scope, so you couldn't use it to break out of the outermost loop. If a condition like that arises, you'd need to do something more complicated depending on exactly what you want, like break from the inner loop, then continue on the outer loop. See here for the documentation on the break keyword. The break C# keyword is similar to the Perl last keyword.

Also, consider taking Dustin's suggestion to just filter out values you don't want to process beforehand:

foreach (var basket in baskets.Where(b => b.IsOpen())) {
foreach (var fruit in basket.Where(f => f.IsTasty())) {
cuteAnimal.Eat(fruit); // Om nom nom. You don't need to break/continue
// since all the fruits that reach this point are
// in available baskets and tasty.
}
}

PHP : How to skip last element in foreach loop

Use a variable to track how many elements have been iterated so far and cut the loop when it reaches the end:

$count = count($array);

foreach ($array as $key => $val) {
if (--$count <= 0) {
break;
}

echo "$key = $val\n";
}

If you don't care about memory, you can iterate over a shortened copy of the array:

foreach (array_slice($array, 0, count($array) - 1) as $key => $val) {
echo "$key = $val\n";
}

Continuously skip an element in foreach loop

Something like this?

$counter = 0;
$items = $xml->channel->item;
foreach ($items as $item) {
$counter++;
if ($counter % 5 == 1) { continue; }
echo $item->link . "<br />";
}

Foreach loop skip existing item

In the first loop your Control is Zero.
You remove the control.
Your next loop gets the next Control. Since its already returned the first control, it now returns the second Control, but since you've removed the Zero control the second Control is now 2.

The key to understanding this behaviour is that the OfType() returns an iterator, not a list. If you returned OfType().ToList() you would get a concrete list that would not be changed when you alter the list you derived it from.

So;

IList<object> x = underlyingList.OfType<object>() returns an iterator.
List<object> y = underlyingList.OfType<object>().ToList() returns a concrete list.

How Can i Skip Loop from a certain Elements In foreach

Loading the desired category name from the controller
Controller:

public function index() {
$dufaultLang = get_dufault_lang();
$data['categories_count'] = mainCategory::where('translation_lang', $dufaultLang)->count();
$categories = mainCategory::where('translation_lang', $dufaultLang)->Selection()->get();

foreach ($categories as $category) {
$data['categories'][] = array(
'id' => $category['id'],
'name' => $this->GetNameByLanguage($category['id'], $dufaultLang),
);
}

return view('admin.maincategories.index', ['data' => $data]);
}

public function GetNameByLanguage($category_id, $language)
{
$TsEns = mainCategory::where('translation_lang', $language)->first();
if ($TsEns->name == null) return "Null";
else return $TsEns->name;
}

Blade:

 <select name="category_id" class="select2 form-control">
<optgroup label="Label text">
@if($data['categories_count'])
@foreach($data['categories'] as $category)
<option value="{{ $category['id'] }}">{{ $category['name'] }}</option>
@endforeach
@endif
</optgroup>
</select>

skip first value for variable inside of foreach loop php

UPDATE #1

Try using array_shift() like this:

foreach ($vid_pix as $vP) {
$Pt2 = get_post_meta($vP, 'photo_time', false);
$Pt = array_shift( $Pt2 ); // get first value
$Pt2[] = 'static value';
var_dump( $Pt, $Pt2 ); // test
}

UPDATE #2

If there's actually just one photo_time meta for each image/attachment (the attachment IDs are in the $vid_pix array), then this should work:

$Pt2 = [];
$n = count( $vid_pix );
for ( $i = 0, $j = 1; $i < $n; $i++, $j++ ) {
$Pt2[] = ( $n === $j ) ? 'static value' :
get_post_meta( $vid_pix[ $j ], 'photo_time', true );
}
echo implode( ', ', $Pt2 ); // test

UPDATE #3

Add the above ($Pt2) code above/before this foreach, then add the $i =>, and change the $Pt as you can see below:

foreach ($vid_pix as $i => $vP) {
$filename = basename( get_attached_file( $vP ));
$Pt = $Pt2[ $i ];
...
}


Related Topics



Leave a reply



Submit