13

I am looking for a way to get the next and next+1 key/value pair in a foreach(). For example:

$a = array('leg1'=>'LA', 'leg2'=>'NY', 'leg3'=>'NY', 'leg4'=>'FL');

foreach($a AS $k => $v){

    if($nextval == $v && $nextnextval == $v){
       //staying put for next two legs
    }

}
Lajos Veres
  • 13,595
  • 7
  • 43
  • 56
danielb
  • 878
  • 4
  • 10
  • 26

6 Answers6

17

You can't access that way the next and next-next values.

But you can do something similar:

$a = array('leg1'=>'LA', 'leg2'=>'NY', 'leg3'=>'NY', 'leg4'=>'FL');

$keys = array_keys($a);
foreach(array_keys($keys) AS $k ){
    $this_value = $a[$keys[$k]];
    $nextval = $a[$keys[$k+1]];
    $nextnextval = $a[$keys[$k+2]];

    if($nextval == $this_value && $nextnextval == $this_value){
       //staying put for next two legs
    }
}
Lajos Veres
  • 13,595
  • 7
  • 43
  • 56
4

I've found the solution with complexity O(n) and does not require seeking through array back and forward:

$a = array('leg1'=>'LA', 'leg2'=>'NY', 'leg3'=>'NY', 'leg4'=>'FL');

// initiate the iterator for "next_val":
$nextIterator = new ArrayIterator($a);
$nextIterator->rewind();
$nextIterator->next(); // put the initial pointer to 2nd position

// initiaite another iterator for "next_next_val":    
$nextNextIterator = new ArrayIterator($a);
$nextNextIterator->rewind();
$nextNextIterator->next();
$nextNextIterator->next(); // put the initial pointer to 3rd position

foreach($a AS $k => $v){

    $next_val = $nextIterator->current();
    $next_next_val = $nextNextIterator->current();

    echo "Current: $v; next: $next_val; next_next: $next_next_val" . PHP_EOL;

    $nextIterator->next();
    $nextNextIterator->next();
}

Just remember to test for valid() if you plan to relay on the $next_val and $next_next_val.

Maciej Sz
  • 11,151
  • 7
  • 40
  • 56
1

Here's one way to do it:

while($current = current($a)) {
    $next = next($a);
    $nextnext = next($a);

    // Comparison logic here

    prev($a); // Because we moved the pointer ahead twice, lets back it up once
}

Example: http://3v4l.org/IGCXW

Note that the loop written this way will never examine the last element in your original array. That could be fixed, although with your current logic it doesn't seem to matter since there are no "more" elements to compare the last one to.

jszobody
  • 28,495
  • 6
  • 61
  • 72
0

Have a look at CachingIterator, as described in this answer:

Peek ahead when iterating an array in PHP

Or use array_keys() is in another answer posted for the same question, e.g.

$keys = array_keys($array);
for ($i = 0; $i < count($keys); $i++) {
    $cur = $array[$keys[$i]];
    $next = $array[$keys[$i+1]];
}
Community
  • 1
  • 1
Peter
  • 2,526
  • 1
  • 23
  • 32
0

You can't simply "stay put" in a loop. I suspect you're looking to do something a lot easier than write custom iterators. If you simply want to ignore entries with duplicate keys, then track the last key and compare it to the current one.

$a = array('leg1'=>'LA', 'leg2'=>'NY', 'leg3'=>'NY', 'leg4'=>'FL');

// Prints LA NY FL
$last_v = null;
foreach ( $a as $k => $v ){
    if ( $last_v == $v ) {
        /**
         *  Duplicate value, so skip it
         */
        continue;
    }
    echo $v.' ';
    $last_v = $v;
}
Dave
  • 3,658
  • 1
  • 16
  • 9
-2

Funny, I'm programming PHP for a decade (with years pause), but I needed one-by-one walk functions just a week ago.

Here you are: next, prev, reset etc. See "see also" section. Also, check array_keys()

ern0
  • 3,074
  • 25
  • 40