【问题标题】:Foreach and unset()Foreach 和 unset()
【发布时间】:2013-05-13 15:17:42
【问题描述】:

遇到了一个小障碍,想知道是否有“最佳实践”方式来解决它。

所以我刚刚了解到“无论如何,一个 php foreach 将在整个数组上执行。测试取消设置迭代中的下一个值。它将在偏移量上进行迭代,但该值将为空。——Kevin Peno 12 月 22 日' 09 点 21:31" 来自How do you remove an array element in a foreach loop?

这是让我感到困惑的第一部分。我正在使用 foreach 遍历一个数组。这是一个搜索功能,所以我要删除我刚刚搜索的元素,所以当循环再次运行时,它会减去那个元素。

如果可能的话,我不想重新索引,但如果必须的话,我可以。

Array
(
[0] => Array
    (
        [0] => a
        [1] => aa
        [2] => aaa
    )

[1] => Array
    (
        [0] => b
        [1] => bb
        [2] => bbb
    )

[2] => Array
    (
        [0] => c
        [1] => cc
        [2] => ccc
    )

[3] => Array
    (
        [0] => d
        [1] => dd
        [2] => ddd
    )

)

foreach($array as $key=>$value) {
   $searchresult[] = search function returns various other keys from array

   foreach($searchresult as $deletionid) {
      unset($array[$deletionid]);
   } 
}

所以在第一次迭代中,它显然使用了 $array[0],但 $searchresults 可能会返回 4,5,6,7。所以这些键从 $array 中删除。

然而,foreach 循环仍然遍历这些并给我返回一堆空数组。

我确实读过How does PHP 'foreach' actually work? 并且得到了一些。

谢谢

【问题讨论】:

  • 您可以在使用 if 子句进行迭代时删除您想要的项目
  • @Fabio 怎么样?我刚刚添加了一个 if(empty($array)) 语句,并且至少摆脱了所有空数组。我想我更感兴趣的是让它不迭代那些,因为它们没有设置。或者这只是一种怪癖。
  • 第一阶段需要删除什么?

标签: php loops foreach unset


【解决方案1】:

在我看来,基于索引删除数组元素的最佳方法是使用 array_* 函数集,例如 array_diff 和 array_intersect(或者在您的情况下为 array_diff_key 和 array_intersect_key)。

$indexes_to_remove = array(2,3,4);
$indexes_to_remove = array_flip($indexes_to_remove);

$array = array_diff_key($array,$indexes_to_remove);

【讨论】:

  • 尝试使用 array_diff_key 和相同的东西。当 foreach 循环开始时,有一个原始的 50 个元素。无论我尝试过什么,它都会通过所有 50 个。除非我在 if(empty($array)) 条件下打破循环。
  • 如果您使用 array_diff,那么您不需要遍历数组 - 遍历它一次以构建您希望删除的索引列表,然后在您离开循环后,diff针对您要删除的元素的数据数组。
  • 我必须循环,这就是搜索的运行方式。我明白你的意思,但这在这种情况下不起作用。我需要继续循环遍历数组,直到它用尽为止,尽管有点混乱。
【解决方案2】:

如果数组保证在某个时候耗尽,你可以使用这个:

while (true) {
    $searchresult[] = search function returns various other keys from array

    foreach($searchresult as $deletionid) {
        unset($array[$deletionid]);
    }
    if (count($array) === 0) {
        break;
    }
}

是的,我知道while (true) 非常邪恶,但我发现在这样的情况下,它完全可以满足需要。 如果你想防止它无限循环,你总是可以添加一个变量,增加每次迭代,当它达到一个永远不会发生的高值时break(比如10 * count($array)

【讨论】:

  • 我会试一试。似乎比 if(!empty($array)) break 更干净。请原谅我的无知,但为什么 while (true) 是邪恶的?不是我用过它,只是为了学习。
  • 因为如果你从未break 脚本将永远运行(当然,除非它达到时间限制)
猜你喜欢
  • 2013-12-31
  • 2019-11-27
  • 1970-01-01
  • 2021-05-14
  • 2012-11-19
  • 2019-05-11
  • 2016-03-10
  • 2020-04-15
  • 2010-11-21
相关资源
最近更新 更多