繁体   English   中英

如何修改foreach内部的数组以处理更多元素,而无需在PHP中进行另一个循环?

[英]How to modify the array inside foreach to process more elements without another loop in PHP?

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

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

注意:处理元素78不会产生更多要处理的项目(即那两个循环确实足够),我只是不喜欢重复代码,所以也许有一些干净的解决方案

我对PHP非常熟悉,但是我真的不知道该语言的某些构造是如何实现的,以及“幕后”将发生什么。

最后的foreach可以通过简单地使用implode来实现。

$items = [1, 3, 7, 8];
var_dump(implode($items));

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

$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 ($itemsToProcess as &$item) {
    ....
    $itemsToProcess[] = $item;
}
unset($value); // always unset the reference

之所以可行,是因为使用元素作为参考会有副作用。 正常调用foreach ,将创建该数组的副本,并对该副本进行迭代。 当您要求foreach提供参考时,永远不会制作此副本(因为您告诉foreach您想使用数组本身)。 这是一个未记录的副作用,它依赖于当前VM中foreach的内部实现,因此,我尝试避免这种情况。 [参考]

http://ideone.com/CNbYGf

您不能在foreach循环中修改输入数组,但是用whilelisteach替换foreach,您可以得到一个类似的简单解决方案,该解决方案可以满足您的需求。

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

这样一来,您将获得在循环中运行时仍需要处理的项目列表,如果要处理的项目很多并且代码很简单,则可以避免队列变得越来越大(只有一个活动行) -仅此而已即可跟踪或处理)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM