unset()的麻烦

时间:2014-06-30 15:58:40

标签: php arrays unset

为了插图而愚蠢

  • PHP 5.27(必填)。
  • 错误报告已开启。

如果数组$unset中存在某个属性$list,我尝试使用数组$list['id']取消设置关联数组$unset值。

但是,我在理解结果方面遇到了很多麻烦:

<?php
$list = array(
  array(
    'id' => 'foo'
  ),
  array(
    'id' => 'bar'
  ),
  array(
    'id' => 'baz'
  ),
  array(
    'id' => 'quix'
  )
);

$unset = array(
  'foo',
);

for ($i=0; $i < count($list); $i++) { 
  echo "Itteration: {$i}" . '<br />';
  echo "Contest ID: {$list[$i]['id']}" . '<br />';
  echo 'Not in Array: ', (!in_array($list[$i]['id'], $unset)) ? 'True' : 'False';

  unset($list[$i]); // Trouble Section
  echo '<br /><br />';
}

输出:

Itteration: 0
Contest ID: foo
Not in Array: False

Itteration: 1
Contest ID: bar
Not in Array: True

无论$unset中的值的数量是多少,我只成功运行了2次迭代。

当我删除unset($list[$i]);后,我们成功遍历$list

Itteration: 0
Contest ID: foo
Not in Array: False

Itteration: 1
Contest ID: bar
Not in Array: True

Itteration: 2
Contest ID: baz
Not in Array: True

Itteration: 3
Contest ID: quix
Not in Array: True

我找不到解释为什么会发生这种情况的解释in the docs。文档讨论的唯一警告是在全局变量函数中使用unset。我甚至尝试unset($GLOBALS['list'][$i])只是为了好玩,结果没有变化。

我在这里缺少什么?

3 个答案:

答案 0 :(得分:7)

这是因为删除项目时count($list)会逐渐变小。

尝试foreach($list as $i=>$item) {

答案 1 :(得分:1)

扩展@ niet的答案:

这两个是完全不同的循环:

for($i = 0; $i < count($list); $i++) {

$cnt = count($list);
for ($i = 0; $i < $cnt; $i++) {

在第一个循环中,每次循环迭代都会计算count(),因此当您从列表中删除项目时,count($list)也会减少。

在第二个循环中,计算列表ONCE,缓存该值,然后每次检查缓存的值。第二个循环将遍历list数组中的所有项目,因为您使用固定的目标柱点。第一个循环每次都将球门柱移近。

答案 2 :(得分:1)

问题是您每次都要计算数组项的数量。它有两个缺点:如果你取消设置项目,就像在这种情况下你的循环不能按预期工作,另外你松散的性能(在每个迭代次数的数组必须再次计算)。

循环的最佳解决方案正在改变:

for ($i=0; $i < count($list); $i++) {

for ($i=0, $c = count($list); $i <$c; ++$i) {
实际上,每次使用for循环时,你都可以使用这种方法。