php 获取 foreach 循环中的下一个元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5096791/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get next element in foreach loop
提问by chchrist
I have a foreach loop and I want to see if there is a next element in the loop so I can compare the current element with the next. How can I do this? I've read about the current and next functions but I can't figure out how to use them.
我有一个 foreach 循环,我想看看循环中是否有下一个元素,以便我可以将当前元素与下一个元素进行比较。我怎样才能做到这一点?我已经阅读了 current 和 next 函数,但我不知道如何使用它们。
Thanks in advance
提前致谢
采纳答案by Stephen
A unique approach would be to reverse the array and thenloop. This will work for non-numerically indexed arrays as well:
一种独特的方法是反转数组然后循环。这也适用于非数字索引数组:
$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;
}
If you are still interested in using the current
and next
functions, you could do this:
如果您仍然对使用current
和next
函数感兴趣,可以这样做:
$items = array('two', 'two', 'three');
$length = count($items);
for($i = 0; $i < $length - 1; ++$i) {
if (current($items) === next($items)) {
// they match
}
}
#2 is probably the best solution. Note, $i < $length - 1;
will stop the loop after comparing the last two items in the array. I put this in the loop to be explicit with the example. You should probably just calculate $length = count($items) - 1;
#2 可能是最好的解决方案。注意,$i < $length - 1;
将在比较数组中的最后两项后停止循环。我把它放在循环中,以便在示例中明确。你可能应该计算一下$length = count($items) - 1;
回答by pronskiy
You could probably use while loop instead of foreach:
您可能可以使用 while 循环而不是 foreach:
while ($current = current($array) )
{
$next = next($array);
if (false !== $next && $next == $current)
{
//do something with $current
}
}
回答by TML
As php.net/foreachpoints out:
正如php.net/foreach指出的那样:
Unless the array is referenced, foreach operates on a copy of the specified array and not the array itself. foreach has some side effects on the array pointer. Don't rely on the array pointer during or after the foreach without resetting it.
除非数组被引用,否则 foreach 会对指定数组的副本而不是数组本身进行操作。foreach 对数组指针有一些副作用。不要在 foreach 期间或之后依赖数组指针而不重置它。
In other words - it's not a very good idea to do what you're asking to do. Perhaps it would be a good idea to talk with someone about why you're trying to do this, see if there's a better solution? Feel free to ask us in ##PHP on irc.freenode.net if you don't have any other resources available.
换句话说 - 做你要求做的事情不是一个好主意。也许与某人讨论您为什么要这样做是个好主意,看看是否有更好的解决方案?如果您没有任何其他可用资源,请随时在 irc.freenode.net 上的 ##PHP 中询问我们。
回答by Mārti?? Briedis
If the indexes are continuous:
如果索引是连续的:
foreach ($arr as $key => $val) {
if (isset($arr[$key+1])) {
echo $arr[$key+1]; // next element
} else {
// end of array reached
}
}
回答by Mārti?? Briedis
if its numerically indexed:
如果它的数字索引:
foreach ($foo as $key=>$var){
if($var==$foo[$key+1]){
echo 'current and next var are the same';
}
}
回答by Dávid Horváth
The general solution could be a caching iterator. A properly implemented caching iterator works with any Iterator, and saves memory. PHP SPL has a CachingIterator, but it is very odd, and has very limited functionality. However, you can write your own lookahead iterator like this:
一般的解决方案可能是缓存迭代器。正确实现的缓存迭代器适用于任何迭代器,并节省内存。PHP SPL 有一个CachingIterator,但它非常奇怪,而且功能非常有限。但是,您可以像这样编写自己的前瞻迭代器:
<?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";
}
}
回答by Andrei Krasutski
You could get the keys/values and index
您可以获得键/值和索引
<?php
$a = array(
'key1'=>'value1',
'key2'=>'value2',
'key3'=>'value3',
'key4'=>'value4',
'key5'=>'value5'
);
$keys = array_keys($a);
foreach(array_keys($keys) as $index ){
$current_key = current($keys); // or $current_key = $keys[$index];
$current_value = $a[$current_key]; // or $current_value = $a[$keys[$index]];
$next_key = next($keys);
$next_value = $a[$next_key] ?? null; // for php version >= 7.0
echo "{$index}: current = ({$current_key} => {$current_value}); next = ({$next_key} => {$next_value})\n";
}
result:
结果:
0: current = (key1 => value1); next = (key2 => value2)
1: current = (key2 => value2); next = (key3 => value3)
2: current = (key3 => value3); next = (key4 => value4)
3: current = (key4 => value4); next = (key5 => value5)
4: current = (key5 => value5); next = ( => )
回答by eclipse31
You could get the keys of the array before the foreach, then use a counter to check the next element, something like:
您可以在 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++;
}
This will work for both simple arrays, such as array(1,2,3)
, and keyed arrays such as array('first'=>1, 'second'=>2, 'thrid'=>3)
.
这对简单数组(例如array(1,2,3)
)和键控数组(例如array('first'=>1, 'second'=>2, 'thrid'=>3)
.
回答by Liquinaut
A foreach loop in php will iterate over a copy of the original array, making next()
and prev()
functions useless. If you have an associative array and need to fetch the next item, you could iterate over the array keys instead:
php 中的 foreach 循环将迭代原始数组的副本,使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]];
}
Since the resulting array of keys has a continuous index itself, you can use that instead to access the original array.
由于生成的键数组本身具有连续索引,因此您可以使用它来访问原始数组。
Be awarethat $next
will be null
for the last iteration, since there is no next item after the last. Accessing non existent array keys will throw a php notice. To avoid that, either:
请注意,这$next
将null
用于最后一次迭代,因为在最后一次之后没有下一项。访问不存在的数组键会抛出一个 php 通知。为避免这种情况,要么:
- Check for the last iteration before assigning values to
$next
- Check if the key with
index + 1
exists witharray_key_exists()
- 在分配值之前检查最后一次迭代
$next
- 检查密钥是否
index + 1
存在array_key_exists()
Using method 2 the complete foreach could look like this:
使用方法 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]];
}
}