it-swarm.com.ru

PHP массив получить следующий ключ/значение в foreach ()

Я ищу способ получить следующую и следующую пару + 1 ключ/значение в foreach (). Например:

$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
    }

}
11
danielb

Вы не можете получить доступ к следующим и следующим-следующим значениям.

Но вы можете сделать что-то подобное:

$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
    }
}
10
Lajos Veres

Я нашел решение со сложностью O(n) и не требует перебора массива назад и вперед:

$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();
}

Просто не забудьте проверить valid(), если вы планируете ретранслировать $next_val и $next_next_val.

2
Maciej Sz

Вот один из способов сделать это:

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
}

Пример: http://3v4l.org/IGCXW

Обратите внимание, что цикл, написанный таким образом, никогда не будет проверять последний элемент в вашем исходном массиве. Это можно исправить, хотя с вашей текущей логикой это, кажется, не имеет значения, так как нет «дополнительных» элементов для сравнения с последним.

1
jszobody

Посмотрите на CachingIterator, как описано в этом ответе:

заглянуть вперед при итерации массива в PHP

Или используйте array_keys () в другом ответе на тот же вопрос, например,.

$keys = array_keys($array);
for ($i = 0; $i < count($keys); $i++) {
    $cur = $array[$keys[$i]];
    $next = $array[$keys[$i+1]];
}
0
Peter

Вы не можете просто «оставаться на месте» в цикле. Я подозреваю, что вы хотите сделать что-то намного проще, чем писать собственные итераторы. Если вы просто хотите игнорировать записи с дублирующимися ключами, отследите последний ключ и сравните его с текущим.

$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;
}
0
Dave