如何在foreach循环中删除数组元素?


127

我想遍历一个数组,foreach以检查是否存在一个值。如果该值确实存在,我想删除包含它的元素。

我有以下代码:

foreach($display_related_tags as $tag_name) {
    if($tag_name == $found_tag['name']) {
        // Delete element
    }
}

找到值后,我不知道如何删除该元素。如何删除?

我必须使用foreach这个问题。可能有替代方法foreach,欢迎您共享它们。

Answers:


219

如果您还获得了密钥,则可以这样删除该项目:

foreach ($display_related_tags as $key => $tag_name) {
    if($tag_name == $found_tag['name']) {
        unset($display_related_tags[$key]);
    }
}

3
有关使用$key => &$tag_name stackoverflow.com/a/2008893/922522进行
贾斯汀

5
请注意,未设置项目的索引数组可以表示为对象,而不是。之后的数组json_encode()。您可以$display_related_tags = array_values ($display_related_tags);foreach循环后解决此问题。
马顿陶

请注意,这里的技巧是在foreach循环中添加一个值;-)
华盛顿先生,

5
请参阅@Neils答案。您将遇到意外的错误,尤其是如果您使用stdClasses数组。你喜欢意外的行为吗?我不是
happy_marmoset 16/09/14

@happy_marmoset尼尔斯的答案无济于事。片段$projects = array_filter($projects, function ($project) { return count($project->roles) > 0; });将结果转换为对象。
Paritosh

36

更好的解决方案是使用以下array_filter功能:

$display_related_tags =
    array_filter($display_related_tags, function($e) use($found_tag){
        return $e != $found_tag['name'];
    });

如PHP 文档所述

由于foreach依赖PHP 5中的内部数组指针,因此在循环内更改它可能会导致意外行为。

在PHP 7中,foreach不使用内部数组指针。


请注意,第三个参数应为ARRAY_FILTER_USE_KEY,以便在此处将键作为$ e传递。
namezero

@namezero好吧,为什么这很重要?
AbraCadaver

@AbraCadaver从文档(php.net/manual/en/function.array-filter.php): ARRAY_FILTER_USE_KEY - pass key as the only argument to callback instead of the value ARRAY_FILTER_USE_BOTH - pass both value and key as arguments to callback instead of the value Default is 0 which will pass value as the only argument to callback instead. 也就是说,在这种情况下再次阅读答案当然并不重要。
namezero

重要提示如果您有兴趣将数组保留为有序数组,则需要在display_related_tags = array_values(display_related_tags);其后调用。
Guyaloni

9
foreach($display_related_tags as $key => $tag_name)
{
    if($tag_name == $found_tag['name'])
        unset($display_related_tags[$key];
}

3
'unlink'取消链接文件,它与变量,或更具体地说,与数组无关。也许您的意思是“未设置”?
2010年

6

与其在数组上执行foreach()循环,不如使用array_search()查找适当的键会更快。在小型数组上,我会与foreach一起使用,以提高可读性,但是对于较大的数组或经常执行的代码,这应该更理想一些:

$result=array_search($unwantedValue,$array,true);
if($result !== false) {
  unset($array[$result]);   
}

需要严格的比较运算符!==,因为array_search()可以返回0作为$ unwantedValue的索引。

同样,上面的示例将仅删除第一个值$ unwantedValue,如果$ unwantedValue可以在$ array中出现多次,则应该使用array_keys()来查找所有值:

$result=array_keys($array,$unwantedValue,true)
foreach($result as $key) {
  unset($array[$key]);
}

有关更多信息,请访问http://php.net/manual/en/function.array-search.php


0

如果您有必须从foreach数组中删除多个值的情况,在这种情况下,您必须为每个值通过引用传递值:我尝试解释这种情况:

foreach ($manSkuQty as $man_sku => &$man_qty) {

               foreach ($manufacturerSkus as $key1 => $val1) {

  // some processing here and unset first loops entries                     
 //  here dont include again for next iterations
                           if(some condition)
                            unset($manSkuQty[$key1]);

                        }
               }
}

在第二个循环中,您要取消设置第一个循环,出于性能目的,条目不会在迭代中再次出现,否则也不会从内存中取消设置,因为它们在内存中存在并且会在迭代中出现。


0

已经有答案可以阐明如何取消设置。与其在所有类中重复执行代码,不如使下面的函数在需要时在代码中使用它。在业务逻辑中,有时您不想公开某些属性。请参阅下面的一个班轮电话以删除

public static function removeKeysFromAssociativeArray($associativeArray, $keysToUnset)
{
    if (empty($associativeArray) || empty($keysToUnset))
        return array();

    foreach ($associativeArray as $key => $arr) {
        if (!is_array($arr)) {
            continue;
        }

        foreach ($keysToUnset as $keyToUnset) {
            if (array_key_exists($keyToUnset, $arr)) {
                unset($arr[$keyToUnset]);
            }
        }
        $associativeArray[$key] = $arr;
    }
    return $associativeArray;
}

致电方式:

removeKeysFromAssociativeArray($arrValues, $keysToRemove);

-1

如前所述,您想对键进行一次foreach,并使用键进行取消设置-但请注意,在迭代过程中更改数组通常是个坏主意,尽管我不确定PHP对此的规则副手。


2
无论如何,PHP foreach都会在整个数组上执行。测试取消设置迭代中下一步的值。它将在偏移量上进行迭代,但是该值将为null。
凯文·佩诺

如果您在迭代过程中不更改数组,那么如何彻底更改数组?可能是卑鄙的意思foreach还是for构造而不是一般的迭代?
Gherman

这更多是对另一个答案的评论,而不是其本身的答案。
险恶胡须
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.