tags:

views:

147

answers:

9

Here's my array:

$array = array(1,2,3,4,5,6,7,8,9,10);

I want to iterate through the array 5 times, do something else, then resume iteration where I left off.

foreach ($array as $value) {
    //do something until key 5
}

//do something else now

//resume...
foreach ($array as $value) {
    //key should start at 6
}

How can I do this? Is there a way to achieve this with a foreach loop?

Update: I realized it would be silly to repeat the same code twice. The reason I was asking this is because I'm using a foreach loop to display table rows. I wanted to display the first five and hide the rest. So this is what I ended up with:

<?php
$counter = 1;
foreach ($array as $object): ?>

    <?php if ($counter > 5): ?>
        <tr style="display: none;">
    <?php else: ?>
        <tr>
    <?php endif; ?>
            <td><?php echo $object->name; ?></td>
        </tr>
    <?php $counter++; ?>

<?php endforeach; ?>
+1  A: 

Just curious, but wouldn't calling a function in the array to do what you need done achieve the same result?

Ian P
normally, yes. but not in this case, no.
Andrew
+1  A: 

something like this:

$counter = 0;
foreach ($array as $value) 
{
if($counter == 5)
{
   do something random;
   $counter++;
   continue;
}
    //do something until key 5
$counter++;
}
Woot4Moo
Thanks for the edit.
Woot4Moo
If I am correct in assuming you mean at the top of the foreach loop that would not work. Because he wants to break out of the execution before the key is processed not after.
Woot4Moo
Yeah, I deleted my comment about 4 seconds after posting it because I double-checked the OP and realized I had misread. :)
Amber
A: 

Is there a reason you need to do this with foreach, as opposed to just for?

Amber
my guess is he isn't concerned with performance
Woot4Moo
A: 

It's a little kloodgy, but it should work:

foreach($array as $key => $value)
{
    $lastkey = $key;

    // do things

    if($key == 5) break;
}

// do other things

foreach($array as $key => $value)
{
    if($key <= $lastkey) continue;

    // do yet more things
}
Luke Dennis
That is quite the unique implementation.
Woot4Moo
A: 

Hi, you can use each() to resume iterating.

$a = array(1,2,3,4);

foreach ($a as $v) {
  if ($v == 2) break;
}

while (list($k, $v) = each($a)) {
  echo "$k = $v\n";
}
jspcal
The each() function returns the current element key and value, and moves the internal pointer forward. (According to the api on w3c) . That break statement would not allow for your foreach to continue executing, which is what he wanted to do.
Woot4Moo
each() resumes from the last cursor position. the question asked how to 'resume' (presumably you have to stop iterating - break - before you can resume.)
jspcal
by breaking it defeats the purpose of that foreach loop. Then again it may just be too small a snippet to be clear.
Woot4Moo
A: 

Use two arrays:

$first_five = array_slice($array, 0, 5);
$remainder = array_slice($array, 5);
Derek Illchuk
+2  A: 

You need to use PHP's internal array pointer.

Something like:

$arr = range(0, 9);
for($i = 0; $i < 5; $i++) {
  print current($arr);
  next($arr);
}

//the pointer should be half way though the array here
Rimian
A: 

I think jspcal had the best answer so far. The only modification I made to his code was to use a do-while loop instead, so it would not skip the element where first loop breaks.

$arr = array(1,2,3,4);

// Prints 1 2
foreach($arr as $v)
{
    if ($v == 3)
    {
        break;
    }
    echo "$v ";
}

// Prints 3 4
do
{
    echo "$v ";
}
while( list($k, $v) = each($arr) );
Kevin
A: 

(For the problem as stated I wouldn't recommend it but:) You can also use the NoRewindIterator.

$array = array(1,2,3,4,5,6,7,8,9,10);
$it = new NoRewindIterator(new ArrayIterator($array));

foreach($it as $x) {
  echo $x;
  if ($x > 4) {
    break;
  }
}
// $it->next();
echo 'taadaa';
foreach($it as $x) {
  echo $x;
}

prints 12345taadaa5678910.
(Note the duplication of the element 5. Uncomment the $it->next() line to avoid that).

VolkerK