在foreach循环内取消设置数组元素

23

以下是我的代码:

<?php

$arr = array(array(2 => 5),
             array(3 => 4),
             array(7 => 10));

foreach ($arr as $v) {
    $k = key($v);
    if ($k > 5) {
        // unset this element from $arr array
    }
}

print_r($arr);

// now I would like to get the array without array(7 => 10) member

你可以看到,我从一个由单个键值数组构成的数组开始,然后遍历该数组并获取当前元素的键(这是一个单个项数组)。

我需要卸载键大于5的数组元素,我该如何做?我可能还需要删除值小于50或任何其他条件的元素。基本上,我需要能够获取当前数组项的键,该键本身是一个只包含单个项的数组。


1
可能是重复的问题:如何在foreach循环中删除数组元素? - 7hi4g0
5个回答

52
foreach($arr as $k => $v) {
    if(key($v) > 5) {
        unset($arr[$k]);
    }
}

1
摊手...我竟然忘记了$k => $v语法,我的记忆力越来越差了。 - Richard Knop
1
使用 $k 和 key($v) 有什么区别,它们不是一样的吗?只是问一下,因为下面的每个示例都使用 key($v),不知道为什么我认为 $k 可以直接使用。 - Haider
2
@Haider,你误解了key($v)的用法。它获取的是子数组$v的键,而不是正在迭代的数组的任何键。对于第一个元素,$k == 0$v == array(2 => 5)key($v) == 2 - cincodenada

16

使用foreach循环迭代数组时,在PHP中安全地从数组中删除元素:

foreach ($arr as $key => $value) {
    if (key($value) > 5) {
        unset($arr[$key]);
    }
}

2
请注意,这实际上并不是 OP 想要的(但你的观点大体上是正确的——在 foreach 循环的上下文中这样做是安全的;其他形式的迭代并不总是安全的)。 - Amber
@Amber,谢谢,我错过了给出的数组数组这一事实,我已经纠正了这个例子。还添加了关于foreach循环的注释。 - Alexander Konstantinov

2
使用key()函数来获取子数组的第一个键。
foreach($arr as $k => $v) {
    if(key($v) > 5) {
        unset($arr[$k]);
    }
}

嗯,不,当我编辑我的回答时,我实际上并不知道你的答案。两个答案相同的事实更多地是因为手头任务的基本性质导致许多人以相同的方式完成它(循环内部本质上与我编辑之前相同;外部基本上是foreach循环的标准)。 - Amber

0

要取消数组元素,我们使用unset()和php函数,如下所示:

foreach($array as $key=>$value)
{
   if(key($value) > 5) 
   {
      unset($array[$key]);
   }
}

0

在迭代集合时添加或删除元素并不是很安全。你可以将想要添加的元素添加到第二个数组中,然后丢弃原始数组,这样做会更加安全。


2
在PHP中,foreach循环默认情况下会迭代提供的数组的副本(除非显式地通过引用传递)。 - Amber
1
参考和复制不是我的重点,也不相关。在迭代期间改变数组是不好的形式。 - Robert McBean
除非你在迭代的数组上进行变异,因为你正在迭代的数组是原始数组的副本。在迭代时变异不同的数组并不是不好的形式,因此从非引用传递的foreach循环中变异原始数组也不是不好的形式,因为原始数组是一个不同的数组。 - Amber
这可能在技术上是正确的,但从语义上讲,开发人员认为他正在迭代中删除某些内容,我认为这是不好的设计,特别是当像foreach这样的关键字暗示着只读遍历时。它可以工作,但这种做法会使代码难以维护。 - Sean Patrick Floyd
1
foreach 如何表明只读?它表明你正在对传递的每个项目执行操作,这正是你要做的。这并不意味着这些项目是否仍然存在于原始数组中。 - Amber

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接