PHP foreach 删除数组元素

Posted

技术标签:

【中文标题】PHP foreach 删除数组元素【英文标题】:PHP foreeach deleting array element 【发布时间】:2012-12-27 03:18:02 【问题描述】:

今天在开发用于博客的文本分析工具时,我发现 php 的行为对我来说非常奇怪,我无法理解它。在规范化文本时,我试图删除最小长度以下的单词,所以我在规范化方法中写了这个:

if ($this->minimumLength > 1) 
    foreach ($string as &$word)
    
        if (strlen($word) < $this->minimumLength) 
            unset($word);
        
    

奇怪的是,这会在我的数组中留下一些低于允许长度的单词。在全班搜索错误后,我试了一下:

if ($this->minimumLength > 1) 
        foreach ($string as $key => $word)
        
            if (strlen($word) < $this->minimumLength) 
                unset($string[$key]);
            
        
    

瞧!这非常有效。现在,为什么会发生这种情况?我查看了PHP Documentation 并指出:

如果通过引用传递的变量在函数内部是 unset(),则只有局部变量被销毁。调用环境中的变量将保持与调用 unset() 之前相同的值。

foreach 是否在这里充当calling environment,因为它有自己的范围?

【问题讨论】:

永远不要修改你正在迭代的东西,因为这种意外行为。 没有回答你关于引用的问题,但最简单、最干净的方法是使用 array_filter() 函数 - php.net/manual/en/function.array-filter.php 谢谢你,我之前使用过array_filter,但用于一些不同的目的。对于从数组中删除元素这样“简单”的操作,我不会想到它,但似乎将它们设置为 false 并在其上运行 array_filter 确实是最清晰的方法 【参考方案1】:

不,这里没有函数调用,也没有通过引用传递变量(您只是在迭代期间通过引用捕获)。

当您通过引用进行迭代时,迭代变量是原始变量的别名。当您使用此别名引用原始别名并修改其值时,更改将在被迭代的数组中保持可见。

但是,当您unset 别名时,原始变量并未“销毁”; alias 只是从符号表中删除。

foreach ($string as $key => &$word)

    // This does not mean that the word is removed from $string
    unset($word);

    // It simply means that you cannot refer to the iteration variable using
    // $word from this point on. If you have captured the key then you can
    // still refer to it with $string[$key]; otherwise, you have lost all handles
    // to it for the remainder of the loop body

【讨论】:

哦....不知何故,我一直认为所有针对值引用的操作都会反映到值本身上。我想我错了,谢谢你澄清这个问题。 @igorpan:一个相关的提示是,当您使用引用进行迭代时,您可能希望在循环体之后立即unset 循环变量;否则,您“冒险”分配给该变量,这将覆盖迭代中的最后一个值。 我知道,即使在循环本身结束后,循环变量也会保持定义。不过,如果有人偶然发现这个问题,它会很有用:)【参考方案2】:

当您在 if 语句中调用 unset($word) 时,您正在删除 $word 变量本身,而不对数组 $string 进行任何更改。

【讨论】:

但是当我通过引用传递它时,为什么会这样呢?我的 foreach 状态 foreach ($string as &amp;$word) 因为它是对原始变量的引用,而不是实际的原始变量;您再次取消设置参考,但原始仍然存在

以上是关于PHP foreach 删除数组元素的主要内容,如果未能解决你的问题,请参考以下文章

PHP - 在foreach循环中取消设置数组元素[重复]

php 删除数组元素+你的年龄

php foreach输出数组只输出元素的第一个字符

php foreach 循环数组要点

如何在 foreach 循环中删除数组元素?

js forEach参数详解,forEach与for循环区别,forEach中如何删除数组元素