如何修改foreach中的数组以处理更多元素,而不在PHP中使用另一个循环?

如何修改foreach中的数组以处理更多元素,而不在PHP中使用另一个循环?,php,arrays,foreach,batch-processing,Php,Arrays,Foreach,Batch Processing,基本上,我想做的事情可以缩小到: $itemsToProcess = array(1,2,3); foreach ($itemsToProcess as $item) { if ($item == 2) { // processing of item 2 produces 2 new items that should be processed: $itemsToProcess[] = 7; $itemsToProcess[] = 8;

基本上,我想做的事情可以缩小到:

$itemsToProcess = array(1,2,3);

foreach ($itemsToProcess as $item) {
    if ($item == 2) {
        // processing of item 2 produces 2 new items that should be processed:
        $itemsToProcess[] = 7;
        $itemsToProcess[] = 8;
        continue;
    }
    echo $item;
}
我想在一个序列中输出1378,但不这样做:

$itemsToProcess = array(1,2,3);
$newItemsToProcess = array();

foreach ($itemsToProcess as $item) {
    if ($item == 2) {
        $newItemsToProcess[] = 7;
        $newItemsToProcess[] = 8;
        continue;
    }
    echo $item;
}

foreach ($newItemsToProcess as $newItem) {
    echo $newItem;
}
注意:对元素7和8的处理不会产生更多要处理的项,即这两个循环就足够了,我只是不喜欢代码重复,所以可能有一些干净的解决方案


我对PHP非常熟悉,但我不知道该语言的某些结构是如何实现的,也不知道幕后发生了什么。

最后一个foreach可以通过简单的使用来实现

为了避免整体迭代,您可以使用:

$items = [1, 2, 3];

$key = array_search(2, $items);
if ($key !== false) {
    unset($items[$key]);
    $items = array_merge($items, [7, 8]); 
}

var_dump(implode($items));

通过引用传递值,则新添加的项目将在同一foreach中处理:

foreach ($itemsToProcess as &$item) {
    ....
    $itemsToProcess[] = $item;
}
unset($value); // always unset the reference
这是因为使用元素作为引用会产生副作用。正常调用foreach时,会创建数组的副本,并对副本进行迭代。当您要求foreach提供引用时,当您告诉foreach您希望使用数组本身时,不会制作此副本。这是一个未记录的副作用,依赖于当前VM中foreach的内部实现,我会尽量避免这种情况


您不能修改foreach循环中的输入数组,但将foreach替换为while、list和each,您可以得到一个类似的简单解决方案,它可以满足您的需要

$itemsToProcess = array(1,2,3);
while(list(, $val) = each($itemsToProcess)) {
    if($val == 2) {
        $itemsToProcess[] = 7;
        $itemsToProcess[] = 8;
        continue;
    }
    echo $val;

}
不要在不合适的时候使用foreach循环。对于while循环来说,这是一个很好的例子,您可以将它用作队列

while($item = array_shift($itemsToProcess))
{
    if ($item == 2)
    {
        $itemsToProcess[] = 7;
        $itemsToProcess[] = 8;
        continue;
    }

    echo $item;
}

这样,当您运行循环时,您将有一个仍然需要处理的项目列表,如果有许多项目需要处理,并且it代码很简单,只有一行活动的代码,那么您将避免队列变得越来越大-没有更多的内容需要跟踪或处理。

您的示例非常基本。为什么不直接说如果$item!=2.回音$item;-我相信你有一个理由,你可以创建一个递归函数,在这里你可以提交你的数组,起始元素和所有的逻辑。我有一个相同的问题,Kai QingI认为他想在数组中添加元素并反映它的逻辑addition@andrew-尽管如此,仍然是原始循环中的一个简单条件。您可能希望扩展此答案。我明白了,但如果OP问这个问题的话,他可能还不太擅长php。本例中的&$项可能无法解释所有的LOL。$item被初始化为引用这一事实如何影响foreach遍历元素的方式?这似乎是一种黑客行为,而不是合适的解决方案。我知道作为引用初始化值的foreach做了什么,并且您引用的文档状态是foreach依赖于内部数组指针,在循环中更改它可能会导致意外行为。我认为您需要创建一些其他示例,更适合你真正想要的then@LihO我认为这个答案几乎满足了你的所有要求。这是Mileth提出的最优雅的解决方案这是一个很好的解决方案,这段代码看起来确实很干净,但是如果$itemsToPRocess是一个大数组,我认为这会在每次迭代时不断更改该数组中的所有键,而且速度会很慢。如果这是一个问题,并且可能是,如果您有一个100k+大小的数组,您可以改为使用array_pop,并将其用作堆栈。这将改变遍历的顺序,但这取决于实际用例,而不是回显可能不成问题的数字。由于php4没有人使用list+each来迭代php数组,这是错误的代码样式。+1因为它本身显示了用于此目的的每个的可能用法。虽然它可能比foreach慢一点,最多几毫秒
while($item = array_shift($itemsToProcess))
{
    if ($item == 2)
    {
        $itemsToProcess[] = 7;
        $itemsToProcess[] = 8;
        continue;
    }

    echo $item;
}