2011-02-23 46 views
35

我有一個foreach循環,我想查看循環中是否有下一個元素,以便可以將當前元素與下一個元素進行比較。我怎樣才能做到這一點?我已閱讀了當前和下一個功能,但我無法弄清楚如何使用它們。獲取foreach循環中的下一個元素

預先感謝

+0

從元素#2開始並將其與元素#1進行比較是否可以接受? – 2011-02-23 21:01:50

+0

不,它必須從1開始 – chchrist 2011-02-23 21:54:35

回答

24

的唯一方法是將扭轉陣列和然後循環。這將非數字索引數組以及工作:

$items = array(
    'one' => 'two', 
    'two' => 'two', 
    'three' => 'three' 
); 
$backwards = array_reverse($items); 
$last_item = NULL; 

foreach ($backwards as $current_item) { 
    if ($last_item === $current_item) { 
     // they match 
    } 
    $last_item = $current_item; 
} 

如果你仍然有興趣使用的currentnext功能,你可以這樣做:

$items = array('two', 'two', 'three'); 
$length = count($items); 
for($i = 0; $i < $length - 1; ++$i) { 
    if (current($items) === next($items)) { 
     // they match 
    } 
} 

#2可能是最好的解。請注意,$i < $length - 1;將在比較數組中的最後兩項後停止循環。我把這個放在循環中,以便在這個例子中明確。你應該纔算$length = count($items) - 1;

6

如果索引AR continious:

foreach($arr as $key => $val){ 
    if(isset($arr[$key+1])){ 
     echo $arr[$key+1]; // next element 
    }else{ 
    //end of array reached 
    } 
} 
+1

這不是真的,試試:array(1 =>'a',0 =>'b',100 =>'c'); – 2014-10-10 05:35:28

+7

@EduardoRomero是的,這就是爲什麼我提到:'如果索引是連續的' – 2014-10-10 10:37:35

4

如果數字索引:

foreach ($foo as $key=>$var){ 

    if($var==$foo[$key+1]){ 
     echo 'current and next var are the same'; 
    } 
} 
1

你可以得到數組的鍵在foreach前,然後用一個計數器來檢查下一個元素,是這樣的:

//$arr is the array you wish to cycle through 
$keys = array_keys($arr); 
$num_keys = count($keys); 
$i = 1; 
foreach ($arr as $a) 
{ 
    if ($i < $num_keys && $arr[$keys[$i]] == $a) 
    { 
     // we have a match 
    } 
    $i++; 
} 

這兩個簡單的陣列工作,如array(1,2,3)和鍵控陣列,如array('first'=>1, 'second'=>2, 'thrid'=>3)

8

作爲php.net/foreach指出:

除非陣列引用,foreach指定數組的一個拷貝,而不是在陣列本身進行操作。 foreach對數組指針有一些副作用。不要在foreach期間或之後依賴數組指針而不重置它。

換句話說 - 做你要做的事不是一個好主意。也許與某人談論你爲什麼試圖這樣做會是一個好主意,看看是否有更好的解決方案?如果您沒有任何其他可用資源,請隨時在irc.freenode.net上的## PHP中提問。

9

你也許可以使用while循環代替的foreach:

while ($current = current($array)) 
{ 
    $next = next($array); 
    if (false !== $next && $next == $current) 
    { 
     //do something with $current 
    } 
} 
+0

我覺得這有幫助......謝謝! – 2015-07-30 18:46:38

+0

請記住,在此之前,您可能必須「重置($ array)」,因爲指針可能未設置爲第一個元素。 – Jonathan 2015-10-16 10:39:01

0

foreach循環在PHP會遍歷原來的數組的副本,使next()prev()功能無用。如果你有一個關聯數組,並需要獲取下一個項目,你可以在數組鍵循環,而不是:

foreach (array_keys($items) as $index => $key) { 
    // first, get current item 
    $item = $items[$key]; 
    // now get next item in array 
    $next = $items[array_keys($items)[$index + 1]]; 
} 

由於計算出的排列鍵的具有連續索引本身,您可以使用,而不是訪問原始數組。

注意$nextnull最後一次迭代,因爲是在最後沒有下一個項目。訪問不存在的數組鍵會拋出一個PHP通知。爲了避免這種情況,可以:

  1. 檢查分配值之前的最後一次迭代$next
  2. 檢查與index + 1鍵與array_key_exists()

使用方法2完整的foreach可能看起來像這樣存在:

foreach (array_keys($items) as $index => $key) { 
    // first, get current item 
    $item = $items[$key]; 
    // now get next item in array 
    $next = null; 
    if (array_key_exists($index + 1, array_keys($items))) { 
     $next = $items[array_keys($items)[$index + 1]]; 
    } 
} 
+1

在每次迭代中使用array_keys?這必須是最慢的解決方案。 – Semra 2017-07-22 11:04:50

2

一般的解決方案可能是一個緩存迭代器。正確實現的緩存迭代器可以與任何Iterator一起使用,並可節省內存。 PHP SPL有一個CachingIterator,但它很奇怪,並且功能非常有限。但是,您可以編寫自己的lookahead迭代器,如下所示:

<?php 

class NeighborIterator implements Iterator 
{ 

    protected $oInnerIterator; 

    protected $hasPrevious = false; 
    protected $previous = null; 
    protected $previousKey = null; 

    protected $hasCurrent = false; 
    protected $current = null; 
    protected $currentKey = null; 

    protected $hasNext = false; 
    protected $next = null; 
    protected $nextKey = null; 

    public function __construct(Iterator $oInnerIterator) 
    { 
     $this->oInnerIterator = $oInnerIterator; 
    } 

    public function current() 
    { 
     return $this->current; 
    } 

    public function key() 
    { 
     return $this->currentKey; 
    } 

    public function next() 
    { 
     if ($this->hasCurrent) { 
      $this->hasPrevious = true; 
      $this->previous = $this->current; 
      $this->previousKey = $this->currentKey; 
      $this->hasCurrent = $this->hasNext; 
      $this->current = $this->next; 
      $this->currentKey = $this->nextKey; 
      if ($this->hasNext) { 
       $this->oInnerIterator->next(); 
       $this->hasNext = $this->oInnerIterator->valid(); 
       if ($this->hasNext) { 
        $this->next = $this->oInnerIterator->current(); 
        $this->nextKey = $this->oInnerIterator->key(); 
       } else { 
        $this->next = null; 
        $this->nextKey = null; 
       } 
      } 
     } 
    } 

    public function rewind() 
    { 
     $this->hasPrevious = false; 
     $this->previous = null; 
     $this->previousKey = null; 
     $this->oInnerIterator->rewind(); 
     $this->hasCurrent = $this->oInnerIterator->valid(); 
     if ($this->hasCurrent) { 
      $this->current = $this->oInnerIterator->current(); 
      $this->currentKey = $this->oInnerIterator->key(); 
      $this->oInnerIterator->next(); 
      $this->hasNext = $this->oInnerIterator->valid(); 
      if ($this->hasNext) { 
       $this->next = $this->oInnerIterator->current(); 
       $this->nextKey = $this->oInnerIterator->key(); 
      } else { 
       $this->next = null; 
       $this->nextKey = null; 
      } 
     } else { 
      $this->current = null; 
      $this->currentKey = null; 
      $this->hasNext = false; 
      $this->next = null; 
      $this->nextKey = null; 
     } 
    } 

    public function valid() 
    { 
     return $this->hasCurrent; 
    } 

    public function hasNext() 
    { 
     return $this->hasNext; 
    } 

    public function getNext() 
    { 
     return $this->next; 
    } 

    public function getNextKey() 
    { 
     return $this->nextKey; 
    } 

    public function hasPrevious() 
    { 
     return $this->hasPrevious; 
    } 

    public function getPrevious() 
    { 
     return $this->previous; 
    } 

    public function getPreviousKey() 
    { 
     return $this->previousKey; 
    } 

} 


header("Content-type: text/plain; charset=utf-8"); 
$arr = [ 
    "a" => "alma", 
    "b" => "banan", 
    "c" => "cseresznye", 
    "d" => "dio", 
    "e" => "eper", 
]; 
$oNeighborIterator = new NeighborIterator(new ArrayIterator($arr)); 
foreach ($oNeighborIterator as $key => $value) { 

    // you can get previous and next values: 

    if (!$oNeighborIterator->hasPrevious()) { 
     echo "{FIRST}\n"; 
    } 
    echo $oNeighborIterator->getPreviousKey() . " => " . $oNeighborIterator->getPrevious() . " ----->  "; 
    echo "[ " . $key . " => " . $value . " ]  -----> "; 
    echo $oNeighborIterator->getNextKey() . " => " . $oNeighborIterator->getNext() . "\n"; 
    if (!$oNeighborIterator->hasNext()) { 
     echo "{LAST}\n"; 
    } 
} 
相關問題