如何从foreach循环内的数组中删除对象?


140

我遍历对象数组,并希望基于其“ 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
        } 
    }
}

有什么建议。谢谢。


Answers:


233
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]);
        } 
    }
}

62
在同一数组的foreach循环中删除数组的元素是否安全?
奥利维尔·庞斯

25
@Oliver:通常它会产生意外的行为,但是您可以使用PHP上的foreach安全地进行操作。在此处阅读测试内容:php.net/manual/en/control-structures.foreach.php#88578
pangon

1
@Paritosh我知道您很久以前就发布了这篇文章,但这是因为PHP使用了关联数组。因此,您有一个已删除的索引:并且它已作为对象编码为JSON。这是有道理的,因为关联数组是“字典”。可能会帮助即将到来的人。
Ryan O'Donnell

1
您真的需要对每个对象执行第二个操作吗?您不能只查询对象的所需“ id”属性吗?为什么还要检查所有其他道具。
htafoya

3
@htafoya不,if(isset($element['id']) && $element['id'] == 'searched_value') { unset($array[$elementKey]); }我认为我刚刚复制并修改了他的代码以向他展示如何unset正确操作时,我只是想。
prodigitalson

2

您的unset语法似乎无效,并且缺少重新索引编制可能会在将来引起麻烦。请参阅: 有关PHP数组的部分

上面显示了正确的语法。还请记住要重新索引的数组值,因此您永远不会索引以前删除的内容。


2

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

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

9
$ element(用于foreach和在foreach中使用)只是对数组中每个元素的引用。unset($ element)只会破坏引用,它不会破坏数组中被引用的元素。
尼古拉斯

3
@Dev_NIX $element = null无法正常工作,其长度$array保持不变,只包含空值
Nico Westerdale

1

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

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

1

注意主要答案。

[['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']

这是因为未设置不会重新索引数组。

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

$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;
        }
    }
}

0

我不是一个PHP程序员,但是我可以说在C#中,您无法在遍历数组时修改数组。您可能想要尝试使用foreach循环来标识元素的索引或要删除的元素,然后在循环之后删除元素。


14
虽然在大多数语言中都是不好的做法,但是PHP中的数组基本上是可以按顺序迭代的关联数组。删除更早的元素不会更改紧随其后的元素的键。
伊格纳西奥·巴斯克斯

22
实际上,这是允许的,因为foreach内部使用的数组是原始数组的副本。这样,修改原始数组是完全安全的。
胡安

68
实际上,这是允许的,因为php非常糟糕。
Eric G
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.