【问题标题】:How to delete object from array inside foreach loop?如何从foreach循环内的数组中删除对象?
【发布时间】:2011-01-19 06:15:15
【问题描述】:

我遍历一个对象数组并想根据它的“id”属性删除其中一个对象,但我的代码不起作用。

foreach($array as $element) {
    foreach($element as $key => $value) {
        if($key == 'id' && $value == 'searched_value'){
            //delete this particular object from the $array
            unset($element);//this doesn't work
            unset($array,$element);//neither does this
        } 
    }
}

任何建议。谢谢。

【问题讨论】:

标签: php foreach unset arrays


【解决方案1】:
foreach($array as $elementKey => $element) {
    foreach($element as $valueKey => $value) {
        if($valueKey == 'id' && $value == 'searched_value'){
            //delete this particular object from the $array
            unset($array[$elementKey]);
        } 
    }
}

【讨论】:

  • 在同一个数组的 foreach 循环中删除数组元素是否安全?
  • @Oliver:通常它会产生意想不到的行为,但你可以在 php 上使用 foreach 安全地做到这一点。在这里阅读以进行测试:php.net/manual/en/control-structures.foreach.php#88578
  • @Paritosh 我知道你很久以前就发布了这个,但这是因为 PHP 使用关联数组。所以你有一个被删除的索引:它被编码为 JSON 作为一个对象。有道理,因为关联数组是“字典”。可能会帮助即将到来的人。
  • 你真的需要为每个做第二个吗?你不能只查询对象所需的“id”属性吗?为什么要检查所有其他道具。
  • @htafoya 不,你可以这样做 if(isset($element['id']) && $element['id'] == 'searched_value') { unset($array[$elementKey]); } 我想当时我只是复制并修改了他的代码,以向他展示如何正确地 unset
【解决方案2】:

注意主要答案。

[['id'=>1,'cat'=>'vip']
,['id'=>2,'cat'=>'vip']
,['id'=>3,'cat'=>'normal']

并调用函数

foreach($array as $elementKey => $element) {
    foreach($element as $valueKey => $value) {
        if($valueKey == 'cat' && $value == 'vip'){
            //delete this particular object from the $array
            unset($array[$elementKey]);
        } 
    }
}

它返回

[2=>['id'=>3,'cat'=>'normal']

而不是

[0=>['id'=>3,'cat'=>'normal']

这是因为 unset 不会重新索引数组。

它重新索引。 (如果我们需要的话)

$result=[];
foreach($array as $elementKey => $element) {
    foreach($element as $valueKey => $value) {
        $found=false;
        if($valueKey === 'cat' && $value === 'vip'){
            $found=true;
            $break;
        } 
        if(!$found) {
           $result[]=$element;
        }
    }
}

【讨论】:

  • 重新索引数组你可以使用$array = array_values($array);
【解决方案3】:

您的 unset 语法似乎无效,并且缺少重新索引可能会在将来造成麻烦。请参阅:the section on PHP arrays

正确的语法如上所示。还要记住 array-values 用于重新索引,因此您永远不会索引您之前删除的内容。

【讨论】:

    【解决方案4】:

    您还可以在 foreach 值上使用引用:

    foreach($array as $elementKey => &$element) {
        // $element is the same than &$array[$elementKey]
        if (isset($element['id']) and $element['id'] == 'searched_value') {
            unset($element);
        }
    }
    

    【讨论】:

    • $element(在foreach内外使用)只是对数组中每个元素的引用。 unset($element) 只会破坏引用,它不会从其数组中破坏引用的元素。
    • @Dev_NIX $element = null 不起作用,$array 的长度保持不变,它只会包含空值
    【解决方案5】:

    这应该可以解决问题.....

    reset($array);
    while (list($elementKey, $element) = each($array)) {
        while (list($key, $value2) = each($element)) {
            if($key == 'id' && $value == 'searched_value') {
                unset($array[$elementKey]);
            }
        }
    }
    

    【讨论】:

      【解决方案6】:

      我不是一个 php 程序员,但我可以说,在 C# 中,您不能在迭代数组时修改它。您可能想尝试使用您的 foreach 循环来识别元素的索引,或者要删除的元素,然后在循环之后删除元素。

      【讨论】:

      • 虽然在大多数语言中这是不好的做法,但 PHP 中的数组基本上是可以按顺序迭代的关联数组。删除较早的元素不会更改其后元素的键。
      • 其实是允许的,因为foreach内部使用的数组是原始数组的副本。这样,修改原始数组是非常安全的。
      • 其实是允许的,因为 php 太坑爹了。
      猜你喜欢
      • 2017-04-13
      • 1970-01-01
      • 2020-02-05
      • 2014-09-08
      • 1970-01-01
      • 2017-02-23
      • 2010-12-29
      • 1970-01-01
      相关资源
      最近更新 更多