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

Posted

技术标签:

【中文标题】如何在 foreach 循环中删除数组元素?【英文标题】:How do you remove an array element in a foreach loop? 【发布时间】:2010-12-29 06:53:49 【问题描述】:

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

我有以下代码:

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

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

我必须使用foreach 来解决这个问题。 foreach 可能有替代品,欢迎分享。

【问题讨论】:

【参考方案1】:

如果你也得到了密钥,你可以像这样删除那个项目:

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

【讨论】:

一些关于使用$key => &$tag_name优化的附加信息***.com/a/2008893/922522 请注意,未设置项的索引数组可能表示为对象,而不是 json_encode() 之后的数组。您可以在 foreach 循环之后使用 $display_related_tags = array_values ($display_related_tags); 解决此问题。 请注意,这里的技巧是在 foreach 循环中添加一个值;-) 请参阅@Neils 的回答。您会遇到意想不到的错误,尤其是当您使用 Array of stdClasses 时。你喜欢意想不到的行为吗?我没有。 @happy_marmoset Neils 的回答没有帮助。 Snippet $projects = array_filter($projects, function ($project) return count($project->roles) > 0; ); 将结果转换为对象。【参考方案2】:

更好的解决方案是使用array_filter 函数:

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

正如 php documentation 读取的那样:

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

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

【讨论】:

请注意,第三个参数应该是 ARRAY_FILTER_USE_KEY 以便在此处将密钥作为 $e 传递。 @namezero 好的,为什么这很重要? @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. 就是说,在这种情况下再次阅读答案当然不会像您声称的那样重要。 重要如果您有兴趣将数组保持为有序数组,则需要在其后调用display_related_tags = array_values(display_related_tags); 那么,我们现在可以说在 PHP 7 中直接从数组中取消设置项是安全的吗?它肯定比使用array_filter 更精简,至少从编码人员的角度来看(我不确定后台的实际实现)。【参考方案3】:
foreach($display_related_tags as $key => $tag_name)

    if($tag_name == $found_tag['name'])
        unset($display_related_tags[$key];

【讨论】:

'unlink' 取消链接文件,它与变量无关,更具体地说,与数组无关。也许您的意思是“未设置”?【参考方案4】:

与其对数组执行 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了解更多信息。

【讨论】:

【参考方案5】:

如果在这种情况下,您必须从 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]);

                        
               

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

【讨论】:

【参考方案6】:

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

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);

【讨论】:

【参考方案7】:

正如已经提到的,您希望使用键执行 foreach,并使用键取消设置 - 但请注意,在迭代期间更改数组通常是一个坏主意,尽管我不确定 PHP 的对此的规则。

【讨论】:

无论如何,php foreach 都将在整个阵列上执行。测试取消设置迭代中的下一个值。它将在偏移量上进行迭代,但值将为空。 如果在迭代过程中不改变数组,那么如何改变数组呢?可能是平均 foreachfor 构造而不是一般的迭代? 这更像是对另一个答案的评论,而不是一个答案本身。

以上是关于如何在 foreach 循环中删除数组元素?的主要内容,如果未能解决你的问题,请参考以下文章

js forEach参数详解,forEach与for循环区别,forEach中如何删除数组元素

js 数组遍历时删除元素

如何在 JavaScript 中迭代数组并删除元素 [重复]

如何仅使用 ForEach 而不是 List 从动态范围中删除

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

PHP - 在foreach循环中取消设置数组元素[重复]