【问题标题】:Unset not working in multiple foreach statements (PHP)取消设置在多个 foreach 语句中不起作用(PHP)
【发布时间】:2013-08-10 01:13:21
【问题描述】:

谁能告诉我这段代码有什么问题:

foreach ($data as $region ):

  foreach ($region as $type):

   foreach ($type as $type2):

    foreach ($type2 as $key=>$val):

    if ($val=='background-color: FFFFFF;' || $val=='')  unset($type2[$key]);

    endforeach;

   endforeach;

  endforeach;

endforeach;

print_r($data) 之后似乎数据数组是一样的,unset 不起作用

【问题讨论】:

标签: php


【解决方案1】:

您的循环正在对原始元素的副本进行操作;对$type2 的更改将不会在$data 中可见,因为$type2 是一个副本。

您可以通过按键遍历所有数组来解决此问题,然后使用这些键索引到 $data 以删除值:

foreach ($data as $k1 => $region ):

  foreach ($region as $k2 => $type):

   foreach ($type as $k3 => $type2):

    foreach ($type2 as $k4 =>$val):

    if ($val=='background-color: FFFFFF;' || $val=='') {
        unset($data[$k1][$k2][$k3][$k4]);
    }

    endforeach;

   endforeach;

  endforeach;

endforeach;

当然这很难看,但是四个嵌套循环就可以了。如果通过引用迭代而不是抓取键,也可以选择,但我个人不喜欢这样,因为在循环结束后通过重用废弃的引用来编写错误的好机会。特别是在这种情况下,我不喜欢它的四次方。

【讨论】:

  • 特别是在这种情况下,我不喜欢您的方法,因为您会生成大量副本(当然取决于数组大小),这比传递引用需要更多的 CPU 时间(和更多的 RAM)。你注意到的唯一优势是在那之后的糟糕代码不会那么糟糕(据我所知)
  • @x4rf41:PHP 使用写时复制,所以我们谈论的是非常轻量级的副本(仅创建额外的 ZVAL)——它与通过引用迭代时完全相同,无论是在 CPU 方面时间和内存。你的断言的依据是什么?
  • @x4rf41:实际上,情况正好相反。比较 thisthis。 PHP 中的引用应该非常 谨慎使用,并且只有在您确切知道自己在做什么的情况下。在这种情况下,我自己也很惊讶地看到引用有多糟糕。
  • 感谢 Jon,您的代码运行良好! x4rf41,我知道这段代码不是“最佳”或优雅的,但我通过一个小尺寸数组循环,所以性能不应该受到影响。
【解决方案2】:

使用它,它应该可以工作:

foreach ($data as &$region ):

  foreach ($region as &$type):

   foreach ($type as &$type2):

    foreach ($type2 as $key=>$val):

    if ($val=='background-color: FFFFFF;' || $val=='')  unset($type2[$key]);

    endforeach;

   endforeach;

  endforeach;

endforeach;

由于& 我放在值变量之前,数组值作为引用传递。 unset 会以这种方式工作

【讨论】:

  • 别忘了取消设置引用!
  • @AmazingDreams 你这是什么意思?代码完全按照需要工作
  • 尝试设置$region = "Some value";,看看$data会发生什么。
  • @AmazingDreams 显然 $data 的相应数组值将被设置
  • 没错。现在在生产环境中尝试它,在应用程序的另一部分。
猜你喜欢
  • 2012-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-28
  • 2013-06-18
  • 2019-08-03
  • 2018-11-19
  • 2020-05-14
相关资源
最近更新 更多