6
$animals = array('cat', 'dog', 'horse', 'elephant');
foreach($animals as $animal)
{
   var_dump($animal);
   next($animals);
}

上面的代码输出:猫、狗、马、大象。我认为该next函数应该移动的内部指针$animals,因此,我应该得到这个输出:猫,马。

如何使 $animals 的内部指针向前(和向后)移动,使其在 foreach 中受到影响?

编辑1:

从手册:

由于 foreach 依赖于内部数组指针,因此在循环内更改它可能会导致意外行为。

尽管如此,我认为这是我需要做的。

编辑2:

根据“您的常识”的链接,我将对我的问题提供更详细的解释。这是一些伪代码:

array $foos;

start loop of $foos
 - do thing #1
 - do thing #2
 - do thing #3
 - keep doing thing #3 while the current value of $foos in the loop meets a certain criteria
loop

当执行返回到循环的开头时,它应该从 #3 访问的最后一个数组继续执行。请注意,该数组是 associative,因此一种for ($i = 0 ...方法不起作用。

4

6 回答 6

10

您可以创建一个ArrayIteratorDocsseekableDocs

由于它是一个迭代器,因此您可以在迭代它时更改位置 ,一些基本示例:

foreach ($iterator as $current) {
    $iterator->next();
}

它应该提供开箱即用的一切。如果没有,您也可以将自己的需求封装Iterator文档中。

于 2012-05-06T20:03:57.083 回答
8

您不应该foreach与直接指针访问混用。如果您想在数组中移动,只需将 替换foreach为 C-style for。它在顶部更冗长,但使用与foreach案例相同的循环体,不同之处在于您可以使用内部指针并获得所需的结果。

$animals = array('cat', 'dog', 'horse', 'elephant');
for ($animal = current($animals), $index = key($animals); 
       $animal; 
       $animal = next($animals), $index = key($animals)) {
  print "$index:";
  var_dump($animal);
  next($animals);
} 

输出:

0:string(3) "cat"
2:string(5) "horse"

使用直通式迭代构造非常具有误导性,例如foreach当您实际上在数组中来回移动时。上面的for循环在这方面更好,但不是很多;在while循环体中明确说明所有细节的循环可能是最佳选择。

于 2012-05-05T04:34:52.717 回答
6

Mark 的解决方案非常接近,但如果数组包含像 0、false 或 "" 这样在第二个 for 循环表达式中评估为 false 的值,则会失败。

该解决方案适用于所有数组,并且更接近 for 循环的“精神”。第一个循环表达式中的 reset() 确保我们从数组的开头开始,这将是 foreach 的情况。for 循环中的第二个表达式需要评估数组指针指向的元素是否存在。如果数组指针指向数组末尾之外或数组为空,则 key() 返回 null。第三个表达式在每次迭代结束时使数组指针前进。

$animals = array('cat', 'dog', 'horse', 'elephant');
for (reset($animals); key($animals) !== null; next($animals)) {
    $animal = current($animals);
    var_dump($animal);
    next($animals);
}

这输出:

string(3) "cat"
string(5) "horse"
于 2012-12-21T01:22:51.097 回答
1

增加&价值

foreach ($variable as $key => &$value) {

}

现在$value参考$variable[$key]地址

于 2014-08-07T14:44:29.353 回答
0

我认为因为他只想跳过元素,所以他可以在 foreach 中使用“继续”和 if 子句。

$skip=array ('dog', 'elephant');
$animals = array('cat', 'dog', 'horse', 'elephant');
foreach($animals as $animal)
{
   if (in_array($animal, $skip)) {
       continue;
   }
   var_dump($animal);
}

这将输出:

string(3) "cat" 
string(5) "horse"

没有 continue 的变体 2 具有相同的效果:

$skip=array ('dog', 'elephant');
$animals = array('cat', 'dog', 'horse', 'elephant');
foreach($animals as $animal)
{
   if (!in_array($animal, $skip)) {
        var_dump($animal);
   }

}
于 2014-04-02T08:26:57.550 回答
-1

您不需要在 foreach 循环结束时手动增加指针 - 它会自动完成。您只需要:

foreach($animals as $animal) {
    var_dump($animal)
}
于 2012-05-05T04:36:18.507 回答