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 &$word)
因为它是对原始变量的引用,而不是实际的原始变量;您再次取消设置参考,但原始仍然存在以上是关于PHP foreach 删除数组元素的主要内容,如果未能解决你的问题,请参考以下文章